Farseen0/scar-pairs huggingface dataset:
HIGH severity: PancakeBunny — Incorrect profit calculation via balanceOf. Very similar PancakeHunny.

Vulnerable code snippet:

[https://www.bscscan.com/address/0xed1443def66e4e8901377467d449499eaba1559a#code#F1#L235](https://www.bscscan.com/address/0xed1443def66e4e8901377467d449499eaba1559a#code#F1#L235)

[https://bscscan.com/address/0x819eea71d3f93bb604816f1797d4828c902

Vulnerable code:
// @dev profits only (underlying + bunny) + no withdraw fee + perf fee
    function getReward() external override {
        uint amount = earned(msg.sender);
        uint shares = Math.min(amount.mul(totalShares).div(balance()), _shares[msg.sender]);
        totalShares = totalShares.sub(shares);
        _shares[msg.sender] = _shares[msg.sender].sub(shares);
        _cleanupIfDustShares();

        amount = _withdrawTokenWithCorrection(amount);
        uint depositTimestamp = _depositedAt[msg.sender];
        uint performanceFee = canMint() ? _minter.performanceFee(amount) : 0;
        if (performanceFee > DUST) {
            _minter.mintForV2(address(_stakingToken), 0, performanceFee, msg.sender, depositTimestamp); //check mintForV2
            amount = amount.sub(performanceFee);
        }

        _stakingToken.safeTransfer(msg.sender, amount);
        emit ProfitPaid(msg.sender, amount, performanceFee);
    }
...
function mintForV2(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint) external payable override onlyMinter {
        uint feeSum = _performanceFee.add(_withdrawalFee);
        _transferAsset(asset, feeSum);

        if (asset == BUNNY) {
            IBEP20(BUNNY).safeTransfer(DEAD, feeSum);
            return;
        }

        uint bunnyBNBAmount = _zapAssetsToBunnyBNB(asset, feeSum, true);
        if (bunnyBNBAmount == 0) return;

        IBEP20(BUNNY_BNB).safeTransfer(BUNNY_POOL, bunnyBNBAmount);
        IStakingRewards(BUNNY_POOL).notifyRewardAmount(bunnyBNBAmount);

        (uint valueInBNB,) = priceCalculator.valueOfAsset(BUNNY_BNB, bunnyBNBAmount); // check valueOfAsset
        uint contribution = valueInBNB.mul(_performanceFee).div(feeSum);
...
function valueOfAsset(address asset, uint amount) public view override returns (uint valueInBNB, uint valueInUSD) {
        if (asset == address(0) || asset == WBNB) {
            valueInBNB = amount;
            valueInUSD = amount.mul(priceOfBNB()).div(1e18);
        }
        else if (keccak256(abi.encodePacked(IPancakePair(asset).symbol())) == keccak256("Cake-LP")) {
            if (IPancakePair(asset).totalSupply() == 0) return (0, 0);

            if (IPancakePair(asset).token0() == WBNB || IPancakePair(asset).token1() == WBNB) {
                valueInBNB = amount.mul(IBEP20(WBNB).balanceOf(address(asset))).mul(2).div(IPancakePair(asset).totalSupply()); //vulnerable point, incorrect calculation
                valueInUSD = valueInBNB.mul(priceOfBNB()).div(1e18);

Vulnerability type: Flashloans, Miscalculation, Yield
HIGH severity: SATURN — The vulnerability in this case occurred due to the synchronization (`sync`) operation being performed on the PancakeSwap (WBNB-SATURN) pool before processing the incoming token transfers. This led to distorted reserves in the PancakeSwap (WBNB-SATURN) pool and a significant increase in the value of SATURN tokens.. https://lunaray.medium.com/saturn-hack-analysis-187eea27725b

Vulnerable code:
uint256 _txFee;
if (tot == uniswapV2Pair) {
    require(amount <= everyTimeSellLimitAmount, "Exchange Overflow"); // sell
    unchecked {
        _txFee = amount * sellFee / commonDiv;
        amount -= _txFee;
    }
} else if (from == uniswapV2Pair) {
    require(amount <= everyTimeBuyLimitAmount, "Exchange Overflow"); // buy
    unchecked {
        _txFee = amount * buyFee / commonDiv;
        amount -= _txFee;
    }
} ... function _transfer(address from, address to, uint256 amount) internal virtual override {
    // Other logic here
} else if (from == uniswapV2Pair) {
    require(amount <= everyTimeBuyLimitAmount, "Exchange Overflow"); // buy
    unchecked {
        _txFee = amount * buyFee / commonDiv;
        amount -= _txFee;
    }

    // buy to lock time
    _lockUserTxToken(to, amount);

    if (_txFee > 0) {
        super._transfer(from, tokenReceiver, _txFee); // vulnerable point
    }

    if (to == uniswapV2Pair) {
        // record disabled block overflow number
        _processBlockOverflow();
        
        uint256 lpb = balanceOf(uniswapV2Pair);
        if (lpb >= _overFlowBurnAmount()) {
            uint256 amountToBurn = amount.mul(burnRate).div(commonDiv);
            uint256 _burnAmount = lpb > amountToBurn ? amountToBurn : lpb; // times burn
            uint256 _blockAmount = _blockRemainingBurnAmount(_burnAmount);
            if (_blockAmount > 0 && isSwapping && automatedMarketMakerPairs[to]) {
                autoLiquidityPairTokens(_blockAmount); // in here
            }
        }
    }

    super._transfer(from, to, amount); // vulnerable point
} ... function lockTheSwap(uint256 amountToBurn) private {
    // pull tokens from pancakePair liquidity and move to dead address permanently
    recordBurn(uniswapV2Pair, amountToBurn);
    // sync price since this is not in a swap transaction!
    IUniswapV2Pair pair = IUniswapV2Pair(uniswapV2Pair);
    pair.sync();
    emit AutoNukeLP();
}

Vulnerability type: Price Manipulation
HIGH severity: WiseLending — Wise Lending's system was exploited due to a rounding issue in the _calculateShares function and manipulation of donation safeguards. The attacker bypassed donation limits and exploited rounding errors through strategic deposits and withdrawals, gaining a disproportionately large share of donations.. https://twitter.com/EXVULSEC/status/1746138811862577515

Vulnerable code:
function _calculateShares(
        uint256 _product,
        uint256 _pseudo,
        bool _maxSharePrice
    )
        private
        pure
        returns (uint256)
    {
        return _maxSharePrice == true
            ? _product % _pseudo == 0
                ? _product / _pseudo
                : _product / _pseudo + 1
            : _product / _pseudo;
    }

Vulnerability type: Precision
HIGH severity: SushiSwap — Sushi RouteProcessor2 does not check user input `route` carefully. The root cause is that ProcessRoute does not perform any checks on the user-provided route parameter, allowing the attacker to exploit this issue by constructing a malicious route parameter that causes the contract to read a Pool created by the attacker.. https://twitter.com/peckshield/status/1644907207530774530 https://twitter.com/SlowMist_Team/status/1644936375924584449 https://twitter.com/AnciliaInc/status/1644925421006520320

Vulnerable code:
/// @notice Processes the route generated off-chain. Has a lock
  /// @param tokenIn Address of the input token
  /// @param amountIn Amount of the input token
  /// @param tokenOut Address of the output token
  /// @param amountOutMin Minimum amount of the output token
  /// @return amountOut Actual amount of the output token
  function processRoute(
    address tokenIn,
    uint256 amountIn,
    address tokenOut,
    uint256 amountOutMin,
    address to,
    bytes memory route //vulnerable point
  ) external payable lock returns (uint256 amountOut) {
    return processRouteInternal(tokenIn, amountIn, tokenOut, amountOutMin, to, route);
  }

Vulnerability type: Access Control, Dex/AMM, Insufficient validation
HIGH severity: RadiantCapital — The attacker exploited a vulnerability in the project's token quantity calculation, leveraging precision expansion and rounding. Through precise control over these factors, the attacker widened profit margins and systematically drained all USDC from the pool by repeatedly executing deposit() and withdraw() operations.. https://twitter.com/beosinalert/status/1742389285926678784?s=61&t=PNVNUmeNmnbzLZBf7IEtjA

Vulnerable code:
function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) public whenNotPaused {
	DataTypes.ReserveData storage reserve = _reserves[asset];

	ValidationLogic.validateDeposit(reserve, amount);

	address aToken = reserve.aTokenAddress;

	reserve.updateState();
	reserve.updateInterestRates(asset, aToken, amount, 0);

	IERC20(asset).safeTransferFrom(msg.sender, aToken, amount);

	if (IAToken(aToken).balanceOf(onBehalfOf) == 0) {
		_usersConfig[onBehalfOf].setUsingAsCollateral(reserve.id, true);
		emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf);
	}

	/// @custom:borrow-and-supply-caps
	ValidationLogic.validateSupplyCap(reserve, amount);

	IAToken(aToken).mint(onBehalfOf, amount, reserve.liquidityIndex);

	emit Deposit(asset, msg.sender, onBehalfOf, amount, referralCode);
}
...
function withdraw(address asset, uint256 amount, address to) external whenNotPaused returns (uint256) {
	DataTypes.ReserveData storage reserve = _reserves[asset];

	address aToken = reserve.aTokenAddress;

	uint256 userBalance = IAToken(aToken).balanceOf(msg.sender);

	uint256 amountToWithdraw = amount;

	if (amount == type(uint256).max) {
		amountToWithdraw = userBalance;
	}

	ValidationLogic.validateWithdraw(
		asset,
		amountToWithdraw,
		userBalance,
		_reserves,
		_usersConfig[msg.sender],
		_reservesList,
		_reservesCount,
		_addressesProvider.getPriceOracle()
	);

	reserve.updateState();

	reserve.updateInterestRates(asset, aToken, 0, amountToWithdraw);

	if (amountToWithdraw == userBalance) {
		_usersConfig[msg.sender].setUsingAsCollateral(reserve.id, false);
		emit ReserveUsedAsCollateralDisabled(asset, msg.sender);
	}

	IAToken(aToken).burn(msg.sender, to, amountToWithdraw, reserve.liquidityIndex);

	emit Withdraw(asset, msg.sender, to, amountToWithdraw);

	return amountToWithdraw;
}

Vulnerability type: Exploit
HIGH severity: BRA — The root cause is due to a logic flaw of the BRA contract, which doubles reward the tax fee to the pancake pair without invoking the sync() function after transferring.. https://twitter.com/BlockSecTeam/status/1612701106982862849

Vulnerable code:
function _transfer(address sender, address recipient, uint amount) internal {
        require(sender != address(0), "BEP20: transfer from the zero address");

        bool recipientAllow = ConfigBRA(BRA).isAllow(recipient);
        bool senderAllowSell = ConfigBRA(BRA).isAllowSell(sender);

        uint BuyPer = ConfigBRA(BRA).BuyPer();
        uint SellPer = ConfigBRA(BRA).SellPer();

        address BuyTaxTo_ = address(0);
        address SellTaxTo_ = address(0);

        _balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");

        uint256 finalAmount = amount;
        uint256 taxAmount = 0;
  
        if(sender == uniswapV2Pair && !recipientAllow){
            taxAmount = amount.div(10000).mul(BuyPer);
            BuyTaxTo_ = ConfigBRA(BRA).BuyTaxTo();
        }

        if(recipient == uniswapV2Pair && !senderAllowSell){
            taxAmount = amount.div(10000).mul(SellPer);
            SellTaxTo_ = ConfigBRA(BRA).SellTaxTo();
        }

        finalAmount = finalAmount - taxAmount;

        if(BuyTaxTo_ != address(0)){
            _balances[BuyTaxTo_] = _balances[BuyTaxTo_].add(taxAmount);
            emit Transfer(sender, BuyTaxTo_, taxAmount);
        }

        if(SellTaxTo_ != address(0)){
            _balances[SellTaxTo_] = _balances[SellTaxTo_].add(taxAmount);
            emit Transfer(sender, SellTaxTo_, taxAmount);
        }
        
        _balances[recipient] = _balances[recipient].add(finalAmount);
        
        if (recipient == address(0)) {
            totalBurn = totalBurn.add(amount);
            _totalSupply = _totalSupply.sub(amount);
            emit Burn(sender, address(0), amount);
        }
        emit Transfer(sender, recipient, finalAmount);
    }

Vulnerability type: ERC20, skim
HIGH severity: PancakeHunny — Incorrect profit calculation via balanceOf. <Vulnerable code snippet analysis>

Vulnerable code:
function getReward() override public nonReentrant updateReward(msg.sender) {
        uint256 reward = rewards[msg.sender];
        if (reward > 0) {
            rewards[msg.sender] = 0;
            rewardsToken.withdraw(reward);
            uint cakeBalance = IBEP20(CAKE).balanceOf(address(this));

            if (address(minter) != address(0) && minter.isMinter(address(this))) {
                uint performanceFee = minter.performanceFee(cakeBalance);
                minter.mintFor(CAKE, 0, performanceFee, msg.sender, depositedAt[msg.sender]); //check mintFor
                cakeBalance = cakeBalance.sub(performanceFee);
            }

            IBEP20(CAKE).safeTransfer(msg.sender, cakeBalance);
            emit RewardPaid(msg.sender, cakeBalance);
        }
    }

function mintFor(address flip, uint _withdrawalFee, uint _performanceFee, address to, uint) override external onlyMinter {
        uint feeSum = _performanceFee.add(_withdrawalFee);
        IBEP20(flip).safeTransferFrom(msg.sender, address(this), feeSum);

        uint hunnyBNBAmount = tokenToHunnyBNB(flip, IBEP20(flip).balanceOf(address(this))); //vulnerable point
        address flipToken = hunnyBNBFlipToken();
....
function tokenToHunnyBNB(address token, uint amount) internal returns(uint flipAmount) {
        if (token == cake) {
            flipAmount = _cakeToHunnyBNBFlip(amount);
        } else {
            // flip
            flipAmount = _flipToHunnyBNBFlip(token, amount);
        }
    }
function _cakeToHunnyBNBFlip(uint amount) private returns(uint flipAmount) {
        swapToken(cake, amount.div(2), _hunny);
        swapToken(cake, amount.sub(amount.div(2)), _wbnb);

        flipAmount = generateFlipToken();  
    }
function generateFlipToken() private returns(uint liquidity) {
        uint amountADesired = IBEP20(_hunny).balanceOf(address(this));
        uint amountBDesired = IBEP20(_wbnb).balanceOf(address(this));

        IBEP20(_hunny).safeApprove(address(ROUTER), 0);
        IBEP20(_hunny).safeApprove(address(ROUTER), amountADesired);
        IBEP20(_wbnb).safeApprove(address(ROUTER), 0);
        IBEP20(_wbnb).safeApprove(address(ROUTER), amountBDesired);

        (,,liquidity) = ROUTER.addLiquidity(_hunny, _wbnb, amountADesired, amountBDesired, 0, 0, address(this), block.timestamp);

Vulnerability type: Miscalculation, Yield
HIGH severity: ArcadiaFi — In the function `vaultManagementAction()`, an attacker can first transfer all assets to a contract he controls, and then re-enter the function `liquidateVault()`to liquidate the vault. In this case, the global variable `"isTrustedCreditorSet"` will be set to `false` and the collateral check can be bypassed.. https://arcadiafinance.medium.com/post-mortem-72e9d24a79b0

Vulnerable code:
function liquidateVault(uint256 openDebt)
        external
        returns (address originalOwner, address baseCurrency_, address trustedCreditor_)
    {
        require(msg.sender == liquidator, "V_LV: Only Liquidator");

        //Cache trustedCreditor.
        trustedCreditor_ = trustedCreditor;

        //Close margin account.
        isTrustedCreditorSet = false;
        trustedCreditor = address(0);
        liquidator = address(0);

        //If getLiquidationValue (total value discounted with liquidation factor to account for slippage)
        //is smaller than the Used Margin: sum of the liabilities of the Vault (openDebt)
        //and the max gas cost to liquidate the vault (fixedLiquidationCost),
        //then the Vault can be successfully liquidated.
        //Liquidations are triggered by the trustedCreditor (via Liquidator), the openDebt is
        //passed as input to avoid the need of another contract call back to trustedCreditor.
        require(getLiquidationValue() < openDebt + fixedLiquidationCost, "V_LV: liqValue above usedMargin");

        //Set fixedLiquidationCost to 0 since margin account is closed.
        fixedLiquidationCost = 0;

        //Transfer ownership of the ERC721 in Factory of the Vault to the Liquidator.
        IFactory(IMainRegistry(registry).factory()).liquidate(msg.sender);

        //Transfer ownership of the Vault itself to the Liquidator.
        originalOwner = owner;
        _transferOwnership(msg.sender);

        emit TrustedMarginAccountChanged(address(0), address(0));

        return (originalOwner, baseCurrency, trustedCreditor_);
    }

Vulnerability type: Reentrancy, Unchecked User Input
MEDIUM severity: - Reentrancy vulnerability: External call before state update allows attacker to recursively call withdraw and drain funds.
- No reentrancy guard: Lacks checks-effects-interactions pattern or mutex.. - Reentrancy vulnerability: External call before state update allows attacker to recursively call withdraw and drain funds.
- No reentrancy guard: Lacks checks-effects-interactions pattern or mutex.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.17;
contract TheDAO {
    mapping(address => uint) public balances;
    function withdraw(uint _amount) public {
        if (balances[msg.sender] >= _amount) {
            msg.sender.call.value(_amount)();
            balances[msg.sender] -= _amount;
        }
    }
}

Vulnerability type: - Reentrancy vulnerability: External call before s
MEDIUM severity: - Unprotected initialization: Any user can call initWallet and set themselves as owner.
- No access control on initWallet.. - Unprotected initialization: Any user can call initWallet and set themselves as owner.
- No access control on initWallet.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.11;
contract ParityWallet {
    address public owner;
    function initWallet(address _owner) public {
        owner = _owner;
    }
    function () public payable {}
}

Vulnerability type: - Unprotected initialization: Any user can call in
MEDIUM severity: - Timestamp dependence: Miners can manipulate block.timestamp to influence contract outcome.
- Insecure randomness: block.timestamp is not a secure source of randomness.. - Timestamp dependence: Miners can manipulate block.timestamp to influence contract outcome.
- Insecure randomness: block.timestamp is not a secure source of randomness.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.18;
contract GovernMental {
    function gamble() public payable {
        require(msg.value > 0);
        if (block.timestamp % 2 == 0) {
            msg.sender.transfer(msg.value * 2);
        }
    }
}

Vulnerability type: - Timestamp dependence: Miners can manipulate bloc
MEDIUM severity: - Denial of Service: If king is a contract that rejects Ether, claimThrone will fail, locking the contract.
- No fallback protection for king address.. - Denial of Service: If king is a contract that rejects Ether, claimThrone will fail, locking the contract.
- No fallback protection for king address.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.18;
contract KingOfEtherThrone {
    address public king;
    uint public thronePrice = 1 ether;
    function claimThrone() public payable {
        require(msg.value >= thronePrice);
        king.transfer(msg.value);
        king = msg.sender;
        thronePrice = msg.value;
    }
}

Vulnerability type: - Denial of Service: If king is a contract that re
MEDIUM severity: - Missing access control: Any user can change the contract owner.
- No restriction on changeOwner function.. - Missing access control: Any user can change the contract owner.
- No restriction on changeOwner function.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.20;
contract Rubixi {
    address public owner;
    function changeOwner(address _owner) public {
        owner = _owner;
    }
}

Vulnerability type: - Missing access control: Any user can change the
MEDIUM severity: - Insecure randomness: block.timestamp and block.difficulty can be manipulated by miners, making random values predictable.. - Insecure randomness: block.timestamp and block.difficulty can be manipulated by miners, making random values predictable.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.24;
contract Fomo3D {
    function getRandom() public view returns (uint) {
        return uint(keccak256(abi.encodePacked(block.timestamp, block.difficulty)));
    }
}

Vulnerability type: - Insecure randomness: block.timestamp and block.d
MEDIUM severity: - Gas limit vulnerability: massBreed can exceed block gas limit if n is large, causing transaction failure and potential DoS.. - Gas limit vulnerability: massBreed can exceed block gas limit if n is large, causing transaction failure and potential DoS.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.18;
contract CryptoKitties {
    uint[] public cats;
    function massBreed(uint n) public {
        for (uint i = 0; i < n; i++) {
            cats.push(i);
        }
    }
}

Vulnerability type: - Gas limit vulnerability: massBreed can exceed bl
MEDIUM severity: - Integer overflow: cnt * _value can overflow, allowing attackers to create tokens from nothing.
- No overflow checks on arithmetic operations.. - Integer overflow: cnt * _value can overflow, allowing attackers to create tokens from nothing.
- No overflow checks on arithmetic operations.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.16;
contract BEC {
    mapping(address => uint256) public balances;
    function batchTransfer(address[] _receivers, uint256 _value) public {
        uint cnt = _receivers.length;
        uint256 amount = cnt * _value;
        require(balances[msg.sender] >= amount);
        for (uint i = 0; i < cnt; i++) {
            balances[_receivers[i]] += _value;
        }
        balances[msg.sender] -= amount;
    }
}

Vulnerability type: - Integer overflow: cnt * _value can overflow, all
MEDIUM severity: - No access control: Any user can withdraw all funds from the contract.
- Unrestricted withdrawAll function.. - No access control: Any user can withdraw all funds from the contract.
- Unrestricted withdrawAll function.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.20;
contract Rubixi {
    function () public payable {}
    function withdrawAll() public {
        msg.sender.transfer(address(this).balance);
    }
}

Vulnerability type: - No access control: Any user can withdraw all fun
MEDIUM severity: - Missing access control: Any user can add themselves as an owner.
- No restriction on addOwner function.. - Missing access control: Any user can add themselves as an owner.
- No restriction on addOwner function.

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.11;
contract ParityMultisig {
    mapping(address => bool) public owners;
    function addOwner(address owner) public {
        owners[owner] = true;
    }
}

Vulnerability type: - Missing access control: Any user can add themsel
MEDIUM severity: - Denial of Service (DoS): If any address in refundAddresses is a contract that reverts or runs out of gas, the entire refundDos function will revert, blocking refunds for all users.
- Gas Limit Vulnerability: The for-loop over refundAddresses can run out of gas if the array is large, causing the transaction to fail and preventing refunds.
- Lack of Pull Pattern: The contract uses a push pattern for refunds, which is less secure and more prone to DoS than the pull pattern.. - Denial of Service (DoS): If any address in refundAddresses is a contract that reverts or runs out of gas, the entire refundDos function will revert, blocking refunds for all users.
- Gas Limit Vulnerability: The for-loop over refundAddresses can run out of gas if the array is large, causing the tr...

Vulnerable code:
pragma solidity ^0.4.15;

contract CrowdFundBad {
  address[] private refundAddresses;
  mapping(address => uint) public refundAmount;

  function refundDos() public {
    for(uint i; i < refundAddresses.length; i++) {
      require(refundAddresses[i].transfer(refundAmount[refundAddresses[i]]));
    }
  }
}

Vulnerability type: - Denial of Service (DoS): If any address in refun