Farseen0/scar-pairs huggingface dataset:
HIGH severity: ST - Stops Transactions. The contract owner can stop transactions for all users.

Vulnerable code:
// contracts/GBCKToken.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

// OpenZeppelin dependencies
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract GBCKToken is ERC20, Ownable {
	uint256 private immutable _cap = 15_000_000 * 10 ** 18;
	uint256 public publicSaleStartDate;
	mapping(address => bool) public allowedTransfer;

	constructor(
		string memory _name,
		string memory _symbol,
		address _tokensReceiver
	) ERC20(_name, _symbol) {
		_transferOwnership(msg.sender);
		uint256 extraTokens = 500_000 * 10 ** 18;
		allowedTransfer[_tokensReceiver] = true;
		allowedTransfer[msg.sender] = true;
		_mint(_tokensReceiver, extraTokens);
		_mint(msg.sender, _cap - extraTokens);
	}

	/**
	 * @dev Returns the cap on the token's total supply.
	 */
	function cap() public view virtual returns (uint256) {
		return _cap;
	}

	/**
	 * @dev See {ERC20-_mint}.
	 */
	function _mint(address account, uint256 amount) internal virtual override {
		require(
			ERC20.totalSupply() + amount <= cap(),
			"GBCKToken: cap exceeded"
		);
		super._mint(account, amount);
	}

	/**
	 * @dev Allows the owner to toggle the allowedTransfer of an address.
	 * @param _address The address to toggle allowedTransfer.
	 */
	function toggleAllowedTransfer(address _address) public onlyOwner {
		allowedTransfer[_address] = !allowedTransfer[_address];
	}

	/**
	 * @dev Allows the owner to set the public sale start date.
	 * @param _publicSaleStartDate The public sale start date.
	 */
	function setPublicSaleStartDate(
		uint256 _publicSaleStartDate
	) public onlyOwner {
		require(
			_publicSaleStartDate > block.timestamp,
			"GBCKToken: invalid date"
		);
		publicSaleStartDate = _publicSaleStartDate;
	}

	/**
	 * @dev See {ERC20-_transfer}.
	 */
	function _transfer(
		address sender,
		address recipient,
		uint256 amount
	) internal virtual override {
		require(
			block.timestamp >= publicSaleStartDate || allowedTransfer[sender],
			"GBCKToken: transfer not allowed"
		);
		super._transfer(sender, recipient, amount);
	}
}


Vulnerability type: CWE-284
HIGH severity: QSP-2 Wrong precision returned in Oracle.amountRequired. Wrong precision returned in Oracle.amountRequired

Vulnerable code:
// SPDX-License-Identifier: Unlicensed

pragma solidity 0.7.6;

import "../OracleCommon.sol";
import "../../interface/IERC20Extended.sol";

/**
 @notice Returns 1:1 in all cases for any pair and any observer. No governable functions. 
 */

contract ICHIPeggedOracle is OracleCommon {

    constructor(address oneTokenFactory_, string memory description, address indexToken_)
        OracleCommon(oneTokenFactory_, description, indexToken_) {}

    /**
     @notice update is called when a oneToken wants to persist observations
     @dev there is nothing to do in this case
     */
    function update(address /* token */) external override {}

    /**
     @notice returns equivalent amount of index tokens for an amount of baseTokens and volatility metric
     @dev token:usdToken is always 1:1 and volatility is always 0
     */
    function read(address /* token */, uint amount) public view override returns(uint amountOut, uint volatility) {
        /// @notice it is always 1:1 with no volatility
        this; // silence mutability warning
        amountOut = amount;
        volatility = 0;
    }

    /**
     @notice returns the tokens needed to reach a target usd value
     @dev token:usdToken is always 1:1 and volatility is always 0
     */
    function amountRequired(address /* token */, uint amountUsd) external view override returns(uint tokens, uint volatility) {
        /// @notice it is always 1:1 with no volatility
        this; // silence mutability warning
        tokens = amountUsd;
        volatility = 0;
    }
}


Vulnerability type: CWE-682|CWE-1339
HIGH severity: BC - Blacklists Addresses. The contract owner can restrict users from transactions by adding them to the `restrictedUsers` mapping, which may be abused by the owner.

Vulnerable code:
//SPDX-License-Identifier: MIT
pragma solidity =0.8.18;

import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import '@openzeppelin/contracts/access/Ownable.sol';

/**
 * @title MediaLicensingToken
 * @author gotbit
 */
contract MediaLicensingToken is ERC20, Ownable {
    mapping(address => bool) public restrictedUsers;

    event RestrictUser(address indexed user);
    event UnrestrictUser(address indexed user);

    constructor(
        string memory name,
        string memory symbol,
        uint256 totalSupply_
    ) ERC20(name, symbol) {
        _mint(msg.sender, totalSupply_);
    }

    /// @notice adds user to restricted list
    /// @dev the user must be not restricted
    function restrictUser(address user) external onlyOwner {
        require(!restrictedUsers[user], 'Already restricted');
        restrictedUsers[user] = true;
        emit RestrictUser(user);
    }

    /// @notice adds user to restricted list
    /// @dev the user must restricted
    function unrestrictUser(address user) external onlyOwner {
        require(restrictedUsers[user], 'Already unrestricted');
        restrictedUsers[user] = false;
        emit UnrestrictUser(user);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 // amount
    ) internal view override {
        require(
            !restrictedUsers[from] && !restrictedUsers[to],
            'Transfer is not allowed'
        );
    }
}


Vulnerability type: CWE-284|CWE-269
MEDIUM severity: Max supply of 500 is not enforced at the token level. The max supply of 500 is enforced in the sale contract instead of at the token level.

Vulnerable code:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "../role/MinterRole.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

/**
 * @title Shrug ERC-721 Token
 */
contract ShrugToken is MinterRole, ERC721 {
    using Strings for uint256;

    // Base URI
    string private baseURI;

    /**
     * @dev Constructor function
     * @param _name name of the token
     * @param _symbol symbol of the token
     * @param baseURI_ base uri of the token
     */
    constructor(
        string memory _name,
        string memory _symbol,
        string memory baseURI_
    ) ERC721(_name, _symbol) {
        _setBaseURI(baseURI_);
    }

    /**
     * @dev Internal Function returns base URI.
     */
    function _baseURI() internal view override returns (string memory) {
        return baseURI;
    }

    /**
     * @dev Public Function returns base URI.
     */
    function getBaseURI() public view returns (string memory) {
        return baseURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs.
     * @param baseURI_ Base uri of the token
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        baseURI = baseURI_;
    }

    /**
     * @dev Mint token function
     * @param to Address of owner
     * @param tokenId Id of the token
     */
    function mint(
        address to,
        uint256 tokenId
    ) external onlyMinter {
        _mint(to, tokenId);
    }

    /**
     * @dev Burn token function
     * @param tokenId Id of the token
     */
    function burn(
        uint256 tokenId
    ) external onlyMinter {
        _burn(tokenId);
    }
}

Vulnerability type: CWE-664
HIGH severity: Visor Finance — Insufficient validation & Reentrancy. Due to from is controllable, attacker can create a custom contract to return specific owner() to pass the check. Then reenter the deposit function via delegatedTransferERC20 function.

Vulnerable code:
// @param visr Amount of VISR transfered from sender to Hypervisor
// @param to Address to which liquidity tokens are minted
// @param from Address from which tokens are transferred
// @return shares Quantity of liquidity tokens minted as a result of deposit
function deposit(
    uint256 visrDeposit,
    address payable from,
    address to
) external returns (uint256 shares) {
    require(visrDeposit > 0, "deposits must be nonzero");
    require(to != address(0) && to != address(this), "to");
    require(from != address(0) && from != address(this), "from");

    shares = visrDeposit;
    if (vvisr.totalSupply() != 0) {
      uint256 visrBalance = visr.balanceOf(address(this));
      shares = shares.mul(vvisr.totalSupply()).div(visrBalance);
    }

    if(isContract(from)) {
      require(IVisor(from).owner() == msg.sender);  **//vulnerable point**
      IVisor(from).delegatedTransferERC20(address(visr), address(this), visrDeposit);
    }
    else {
      visr.safeTransferFrom(from, address(this), visrDeposit);
    }

    vvisr.mint(to, shares);
}

Vulnerability type: Dex/AMM, Insufficient validation, Reentrancy
HIGH severity: NGFS — Access Control. https://blog.solidityscan.com/ngfs-token-hack-analysis-7a17f183e6a1

Vulnerable code:
function setProxySync(address _addr) external {
    require(_addr != ZERO, "ERC20: library to the zero address");
    require(_addr != DEAD, "ERC20: library to the dead address");
    require(msg.sender == _uniswapV2Proxy, "ERC20: uniswapPrivileges");

    _uniswapV2Library = IPancakeLibrary(_addr);
    _isExcludedFromFee[_addr] = true;
}
function reserveMultiSync(address syncAddr, uint256 syncAmount) public { // <-- vulnerable point - public
    require(_msgSender() == address(_uniswapV2Library), "ERC20: uniswapPrivileges");
    require(syncAddr != address(0), "ERC20: multiSync address is zero");
    require(syncAmount > 0, "ERC20: multiSync amount equal to zero");
    _balances[syncAddr] = _balances[syncAddr].air(syncAmount);
    _isExcludedFromFee[syncAddr] = true;
}

Vulnerability type: Access Control
HIGH severity: EarningFram — The attack exploited both reentrancy and a flawed business logic in the share burning process, where withdrawals were processed before shares were burnt.. https://twitter.com/Phalcon_xyz/status/1689182459269644288

Vulnerable code:
function withdraw(uint256 assets, address receiver) public virtual nonReentrant unPaused returns (uint256 shares) {
    require(assets != 0, "ZERO_ASSETS");
    require(assets <= maxWithdraw, "EXCEED_ONE_TIME_MAX_WITHDRAW");

    // Total Assets amount until now
    uint256 totalDeposit = convertToAssets(balanceOf(msg.sender));

    require(assets <= totalDeposit, "EXCEED_TOTAL_DEPOSIT");

    // Calculate share amount to be burnt
    shares = (totalSupply() * assets) / totalAssets();

    // Calls Withdraw function on controller
    (uint256 withdrawn, uint256 fee) = IController(controller).withdraw(assets, receiver);

    require(withdrawn > 0, "INVALID_WITHDRAWN_SHARES");

    // Shares could exceed balance of caller
    if (balanceOf(msg.sender) < shares) shares = balanceOf(msg.sender);

    _burn(msg.sender, shares);

    emit Withdraw(address(asset), msg.sender, receiver, assets, shares, fee);
}

Vulnerability type: Reentrancy
HIGH severity: ApeCoin — Incorrect airdrop calculation. function getClaimableTokenAmountAndGammaToClaim() to calculate the amount of ApeCoin to claim based on how many NFT the caller has and it doesn't consider how long the caller owns those NFTs.

Vulnerable code:
function claimTokens() external whenNotPaused {
        require(block.timestamp >= claimStartTime && block.timestamp < claimStartTime + claimDuration, "Claimable period is finished");
        require((beta.balanceOf(msg.sender) > 0 || alpha.balanceOf(msg.sender) > 0), "Nothing to claim");

        uint256 tokensToClaim;
        uint256 gammaToBeClaim;

        (tokensToClaim, gammaToBeClaim) = getClaimableTokenAmountAndGammaToClaim(msg.sender); //vulnerable point, check reward

        for(uint256 i; i < alpha.balanceOf(msg.sender); ++i) {
            uint256 tokenId = alpha.tokenOfOwnerByIndex(msg.sender, i);
            if(!alphaClaimed[tokenId]) {
                alphaClaimed[tokenId] = true;
                emit AlphaClaimed(tokenId, msg.sender, block.timestamp);
            }
        }
function getClaimableTokenAmountAndGammaToClaim(address _account) private view returns (uint256, uint256)
    {
        uint256 unclaimedAlphaBalance;
        for(uint256 i; i < alpha.balanceOf(_account); ++i) {
            uint256 tokenId = alpha.tokenOfOwnerByIndex(_account, i);
            if(!alphaClaimed[tokenId]) {
                ++unclaimedAlphaBalance;
            }

Vulnerability type: ERC20, Flashloans, claimTokens
HIGH severity: Li.Fi — Arbitrary call via swap. _swapData is controllable

Vulnerable code:
function swap(bytes32 transactionId, SwapData calldata _swapData) internal {
    uint256 fromAmount = _swapData.fromAmount;
    uint256 toAmount = LibAsset.getOwnBalance(_swapData.receivingAssetId);
    address fromAssetId = _swapData.sendingAssetId;
    if (!LibAsset.isNativeAsset(fromAssetId) && LibAsset.getOwnBalance(fromAssetId) < fromAmount) {
        LibAsset.transferFromERC20(_swapData.sendingAssetId, msg.sender, address(this), fromAmount);
    }

    if (!LibAsset.isNativeAsset(fromAssetId)) {
        LibAsset.approveERC20(IERC20(fromAssetId), _swapData.approveTo, fromAmount);
    }

    // solhint-disable-next-line avoid-low-level-calls
    (bool success, bytes memory res) = _swapData.callTo.call{ value: msg.value }(_swapData.callData); //vulnerable point
    if (!success) {
        string memory reason = LibUtil.getRevertMsg(res);
        revert(reason);
    }

    toAmount = LibAsset.getOwnBalance(_swapData.receivingAssetId) - toAmount;
    emit AssetSwapped(
        transactionId,
        _swapData.callTo,
        _swapData.sendingAssetId,
        _swapData.receivingAssetId,
        fromAmount,
        toAmount,
        block.timestamp
    );
}

Vulnerability type: Aggregation, Bridge, CrossChain
HIGH severity: PikeFinance — uninitialized proxy. https://blog.solidityscan.com/pike-finance-hack-analysis-30bcca9f072b https://quillaudits.medium.com/decoding-pike-finance-exploit-quillaudits-40a1662d3f8a

Vulnerable code:
function initialize(
    address _console, 
    address _rng, 
    address _vault, 
    address _gameProvider, 
    uint16 _minPos, 
    uint16 _maxPos
) public nonPayable {
    require(msg.data.length - 4 >= 192);
    v0 = v1 = !stor_b_2_2;
    if (!stor_b_2_2) {
        v0 = v2 = !stor_b_1_1;
    }
    if (!v0) {
        v0 = v3 = !this.code.size;
        if (!bool(this.code.size)) {
            v0 = 1 = stor_b_1_1;
        }
    }

    require(v0, Error("Initializable: contract is already initialized"));
    stor_b_1_1 = 1;
    if (!stor_b_2_2) {
        stor_b_2_2 = 1;
    }

    _gateway = _console;
    owner_2_0_19 = _rng;
    _endpoint = _vault;
    stor_4_0_19 = _gameProvider;
    _isActive = 0x1 | (bytes31(msg.sender << 40) | 0xffffffffffffffffffffffffffffffffffffffffff0000ffffff00 & (_maxPos << 24 | 0xffffffffffffffffffffffffffffffffffffffffff0000ffffff00 & _minPos << 8 | _isActive & 0xffffffffffffffffffffffffffffffffffffffffff0000000f));
    _nativeAsset = 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee;
    if (!stor_b_2_2) {
        stor_b_2_2 = 0;
        emit Initialized(1);
    }
}

Vulnerability type: uninitialized
HIGH severity: MooCAKECTX — The reward calculation on the victim contract is not time-related, and the attacker bypasses the `isContract` validation by performing an attack in the constructor.. https://twitter.com/BeosinAlert/status/1589501207181393920 https://twitter.com/CertiKAlert/status/1589428153591615488

Vulnerable code:
/**
     * @dev Core function of the strat, in charge of collecting and re-investing rewards.
     * 1. It claims rewards from the MasterChef & SmartChef
     * 2. It swaps the {output} token for {cake}
     * 3. It charges the system fee and sends it to BIFI stakers.
     * 4. It re-invests the remaining profits.
     */
    function harvest() public {
        require(!Address.isContract(msg.sender), "!contract");
        IMasterChef(masterchef).leaveStaking(0);
        ISmartChef(smartchef).deposit(0);
        doswap();
        dosplit();
        deposit();
    }

Vulnerability type: Flashloans
HIGH severity: DPC — Incorrect Reward calculation. To increase the reward by calling the claimStakeLp function in the contract. The reward calculated in the function claimStakeLp() is the accumulation of the previous reward and the reward calculated by getClaimQuota().

Vulnerable code snippet:
[https://bscscan.com/address/0xB75cA3C3e99747d0e2F6e75A

Vulnerable code:
function claimStakeLp(address _from ,uint256 Amountwei) public {
    require(Amountwei > 0,"Quantity error");
    require(_from==msg.sender,"error");
    require(dpcLp[_from] >= Amountwei ,"Insufficient authorization limit");
    IERC20(LpContract).transfer(_from,Amountwei);

    oldClaimQuota[_from] = oldClaimQuota[_from].add(getClaimQuota(_from)); //vulnerable point

    dpcLp[_from] = dpcLp[_from].sub(Amountwei);

    time=currTimeStamp();
    dpcLpTime[_from] = time;

    dpcLpTotal = dpcLpTotal.sub(Amountwei);
}

function getClaimQuota(address addr) public view returns (uint256) {
    uint256 ClaimQuota;
    if(dpcAirdrop[addr] > 0 && dpcLp[addr]>0){
        uint256 QuotastartTime;
        uint256 limit = 50 * 10**18;
        uint256 LpQuotaNum = dpcLp[addr].mul(getLpPrice()).mul(lpQuota).div(100);
        uint256 secondQuota;
        if(getDpcPrice()>0){
            secondQuota = LpQuotaNum.div(24*60*60).div(getDpcPrice());
        }

        uint256 limitSecondQuota = limit.div(24*60*60);
        if(secondQuota > limitSecondQuota){
            secondQuota = limitSecondQuota;
        }
        uint256 nowTime = currTimeStamp();

        if(dpcLpTime[addr]>ClaimQuotaTime[addr]){
            QuotastartTime = dpcLpTime[addr];
        }else{
            QuotastartTime = ClaimQuotaTime[addr];
        }
        ClaimQuota = (nowTime.sub(QuotastartTime)).mul(secondQuota);
        if(ClaimQuota > dpcAirdrop[addr]){
            ClaimQuota = dpcAirdrop[addr];
        }
    }else{
        ClaimQuota = 0;
    }
    ClaimQuota = ClaimQuota.add(oldClaimQuota[addr]); //vulnerable point

    return ClaimQuota;
}

Vulnerability type: ERC20, Miscalculation
HIGH severity: YYStoken — Root cause is the same as STM token exploit, wrong calculation of liquidity amount to remove in "sell" function.. https://x.com/0xNickLFranklin/status/1799610045589831833

Vulnerable code:
function sell(uint256 amount) external {
    eve_token_erc20.transferFrom(msg.sender, address(this), amount);
    (, uint256 r1, ) = inner_pair.getReserves();  // <-- vulnerable point
    uint256 lpAmount = amount*inner_pair.totalSupply()/(2*r1);
    uniswapV2Router.removeLiquidity(address(usdt_token_erc20),address(eve_token_erc20),lpAmount,0,0,msg.sender,block.timestamp);
}

Vulnerability type: Business Logic Flaw
HIGH severity: ElasticSwap — Business Logic Flaw. 
ElasticSwap is an AMM focused on elastic supply tokens.
An elastic supply (or rebase) token works in a way that the circulating supply expands or contracts due to changes in token price.
ElasticSwap adapts to the elastic supply changes without the need for someone to call a function on the pool itself after a change (rebase) happens.. https://quillaudits.medium.com/decoding-elastic-swaps-850k-exploit-quillaudits-9ceb7fcd8d1a

Vulnerable code:
function addLiquidity(uint256 _baseTokenQtyDesired, uint256 _quoteTokenQtyDesired, uint256 _baseTokenQtyMin, uint256 _quoteTokenQtyMin, address _liquidityTokenRecipient){//vulnerable point
    MathLib.TokenQtys memory tokenQtys = MathLib.calculateAddLiquidityQuantities(, , , , IERC20(baseToken).balanceOf(address(this)), totalSupply, internalBalances);
    internalBalances.kLast = internalBalances.baseTokenReserveQty * internalBalances.quoteTokenReserveQty;
}

function removeLiquidity(uint256 _liquidityTokenQty, uint256 _baseTokenQtyMin, uint256 _quoteTokenQtyMin, address _tokenRecipient){//vulnerable point
    uint256 baseTokenReserveQty  = IERC20(baseToken).balanceOf(address(this));
    uint256 quoteTokenReserveQty = IERC20(quoteToken).balanceOf(address(this));
    
    uint256 baseTokenQtyToReturn  = (_liquidityTokenQty * baseTokenReserveQty) / totalSupplyOfLiquidityTokens;
    uint256 quoteTokenQtyToReturn = (_liquidityTokenQty * quoteTokenReserveQty) / totalSupplyOfLiquidityTokens;

    uint256 internalBaseTokenReserveQty = internalBalances.baseTokenReserveQty;
    uint256 baseTokenQtyToRemoveFromInternalAccounting = (_liquidityTokenQty * internalBaseTokenReserveQty) / totalSupplyOfLiquidityTokens;
    
    internalBalances.baseTokenReserveQty = internalBaseTokenReserveQty = internalBaseTokenReserveQty - baseTokenQtyToRemoveFromInternalAccounting;
    
    internalBalances.quoteTokenReserveQty = internalQuoteTokenReserveQty = internalQuoteTokenReserveQty - quoteTokenQtyToReturn;  // @audit: doesn't sync the reserves (as in UniswapPair.burn())
    
    IERC20(baseToken).safeTransfer(_tokenRecipient, baseTokenQtyToReturn);
    IERC20(quoteToken).safeTransfer(_tokenRecipient, quoteTokenQtyToReturn);
}

Vulnerability type: Incorrect logic
HIGH severity: NeverFall — The root cause lies in the logic that evaluates the price of the token, which is based on the Pair from PancakeSwap. If you examine the sell() function of the NeverFall contract, you can easily identify the cause.. https://twitter.com/BeosinAlert/status/1653619782317662211 https://twitter.com/kalos_security/status/1668092312906514433

Vulnerable code:
function buy(uint256 amountU) public returns(uint256){
    require(startBuy,"not start");
    //收usdt
    IERC20(usdtAddress).safeTransferFrom(msg.sender,address(this),amountU);

    uint256 beforeLiquidityAmount = balanceOf(address(this));
    //90%加池子
    IERC20(usdtAddress).approve(uniswapV2Router,amountU);
    addLiquidity(initSupply, amountU * buyAddLiqFee / 100);
    uint256 afterLiquidityAmount = balanceOf(address(this));
    //5%的usdt购买
    buySwap(amountU * buySwapFee / 100);
    super._transfer(address(this), msg.sender, beforeLiquidityAmount - afterLiquidityAmount - balanceOf(pairTempAddress)); 
    super._transfer(pairTempAddress, address(this), balanceOf(pairTempAddress));
    //营销
    IERC20(usdtAddress).safeTransfer(marketingAddress,amountU * buyMarketingFee / 100);
    emit BuyNF(msg.sender,amountU);
    return beforeLiquidityAmount - afterLiquidityAmount - balanceOf(pairTempAddress);
} 

function sell(uint256 amount) public returns(uint256){
    super._transfer(msg.sender, address(this), amount);
    //撤池子 退给用户U
    uint256 balanceNF = this.balanceOf(uniswapV2Pair);
    uint256 pairTotalSupply = IERC20(uniswapV2Pair).totalSupply();
    uint256 needLiquidity = amount * pairTotalSupply / balanceNF; //vulnerable point
    
    uint256 beforeU = IERC20(usdtAddress).balanceOf(address(this));
    removeLiquidity(needLiquidity,amount * 90 / 100,0);
    uint256 afterU = IERC20(usdtAddress).balanceOf(address(this));
    uint256 outU =  afterU - beforeU;

    IERC20(usdtAddress).safeTransfer(msg.sender, outU * sellFee / 100);
    //营销
    IERC20(usdtAddress).safeTransfer(marketingAddress,outU * sellMarketingFee / 100);
    emit SellNF(msg.sender,amount,outU);
    return outU * sellFee / 100;
}

Vulnerability type: Sandwich