Farseen0/scar-pairs huggingface dataset:
HIGH severity: MaestroRouter2 — The `0x9239127f` function in the Maestro Router 2 contract has an external call vulnerability. Attackers can pass in a token address and use the `transferFrom` function with the victim's and their own addresses to transfer the victim's tokens.. https://twitter.com/Phalcon_xyz/status/1717014871836098663 https://twitter.com/BeosinAlert/status/1717013965203804457

Vulnerable code:
function @x9239127f(uint256 varg0, bytes varg1, uint256 varg2, uint256 varg3) public payable {
    require(~3 + msg.data.length >= 128);
    require(!(address(varg1) - varg1));
    require(varg1 <= uint64.max);
    require(4 + varg1 + 31 < msg.data.length);
    require(varg1.length <= uint64.max);
    require(!(bool(varg3) - varg3));
    require(!bool(msg.value < varg2), "Tip can't be bigger than tx value");
    require(msg.value - varg2 <= msg.value, Panic(17)); // arithmetic overflow or underflow
    v0 = v1 = 1789;
    v2 = v2 = 5518;
    CALLDATACOPY(v3.data, varg1.data, varg1.length);
    MEM[v3.data + varg1.length] = 0;
    v4 = v5 = varg0.call(v3.data).value(msg.value - varg2).gas(msg.gas);
    v6 = v5;
    v7 = v0;
    if (varg3) {
        ...
    }
}

Vulnerability type: Arbitrary call
HIGH severity: OlympusDAO — insufficient validation. Due to token_ is controllable and does not validate properly on BondFixedExpiryTeller, attacker can create a custom contract to drain out the fund on BondFixedExpiryTeller.

Vulnerable code:
/// @inheritdoc IBondFixedExpiryTeller
    function redeem(ERC20BondToken token_, uint256 amount_) external override nonReentrant {**//vulnerable point,** insufficient validation
        if (uint48(block.timestamp) < token_.expiry())
            revert Teller_TokenNotMatured(token_.expiry());
        token_.burn(msg.sender, amount_);
        token_.underlying().transfer(msg.sender, amount_); **//vulnerable point, custom contract return OHM.**
    }

Vulnerability type: DAO, Insufficient validation
HIGH severity: Sandbox LAND — incorrect access control.. In the past, the _burn function that was set to be called was set in a public state. Even though there is a require(from == owner, “not owner”); in the function, the from in the function can still be constructed by any caller. This could results in anyone burning other players NFTs at will.

Vulnerable code:
function _burn(address from, address owner, uint256 id) public {
        require(from == owner, "not owner");
        _owners[id] = 2**160; // cannot mint it again
        _numNFTPerAddress[from]--;
        emit Transfer(from, address(0), id);
    }

Vulnerability type: Access Control
HIGH severity: MetaDragon — Incorrect logic check. if (to == address(this) || to == erc721) {transform(value);} allows for unrestricted minting. if (to == address(this) || to == erc721) {transform(value);} allows for unrestricted minting

Vulnerable code:
function _update(address from, address to, uint256 value) internal override { ... if (to == address(this) || to == erc721) { transform(value); } ... }

Vulnerability type: Business Logic Flaw
HIGH severity: FFIST — The root cause is in `_airdrop()` function, the airdrop address can be calculated and it could overwrite any balance of an address to a specific number. Attacker can overwrote the balance of the swap, causing the K change thus a big gain on the swap. The random seed is not randomized which is  easy to construct 'to' and 'tAmount' here to get an arbitrary airdropAddress address and that address will be used for balance overwritten.. https://x.com/Phalcon_xyz/status/1681869807698984961

Vulnerable code:
function _airdrop(address from, address to, uint256 tAmount) private {
        uint256 num = 4;
        uint256 seed = (uint160(lastAirdropAddress) | block.number) ^ (uint160(from) ^ uint160(to));
        uint256 airdropAmount = 1;
        address airdropAddress;
        for (uint256 i; i < num;) {
            airdropAddress = address(uint160(seed | tAmount));
            _balances[airdropAddress] = airdropAmount;
            emit Transfer(airdropAddress, airdropAddress, airdropAmount);
        unchecked{
            ++i;
            seed = seed >> 1;
        }
        }
        lastAirdropAddress = airdropAddress;
    }

Vulnerability type: Bad randomness
HIGH severity: Omni NFT — safeTransferFrom in burn function. project without nonReentrant protection.. safeTransferFrom in burn function. project without nonReentrant protection.

Vulnerable code:
function executeWithdrawERC721(
        mapping(address => DataTypes.ReserveData) storage reservesData,
        mapping(uint256 => address) storage reservesList,
        DataTypes.UserConfigurationMap storage userConfig,
        DataTypes.ExecuteWithdrawERC721Params memory params
    ) external returns (uint256) {
        DataTypes.ReserveData storage reserve = reservesData[params.asset];
        DataTypes.ReserveCache memory reserveCache = reserve.cache();

        reserve.updateState(reserveCache);
        uint256 amountToWithdraw = params.tokenIds.length;

        bool withdrwingAllCollateral = INToken(reserveCache.xTokenAddress).burn(
            msg.sender,
            params.to,
            params.tokenIds,
            reserveCache.nextLiquidityIndex
        ); /// @inheritdoc INToken
    function burn(
        address from,
        address receiverOfUnderlying,
        uint256[] calldata tokenIds,
        uint256 index
    ) external virtual override onlyPool returns (bool) {
        bool withdrawingAllTokens = _burnMultiple(from, tokenIds);

        if (receiverOfUnderlying != address(this)) {
            for (uint256 index = 0; index < tokenIds.length; index++) {
                IERC721(_underlyingAsset).safeTransferFrom( //vulnerable point
                    address(this),
                    receiverOfUnderlying,
                    tokenIds[index]
                );
            }
        }

Vulnerability type: ERC721, Flashloans, Reentrancy
HIGH severity: WIFCOIN_ETH — Double claimEarned, Each time the `claimEarned` function is called, the code iterates through all the stakes and accumulates the calculated `_earned` amount. However, after calculating the rewards, the already calculated rewards are not marked as claimed. As a result, the next time `claimEarned` is called, it will recalculate those already claimed rewards, allowing users to claim rewards multiple times.. https://x.com/ChainAegis/status/1802550962977964139

Vulnerable code:
function claimEarned(uint256 _stakingId, uint256 _burnRate) public override {
        require(_burnRate == 10 || _burnRate == 25 || _burnRate == 40, "Invalid burn rate");

        uint256 _earned = 0;
        Plan storage plan = plans[_stakingId];

        require(stakes[_stakingId][msg.sender].length > 0, "No stakes found");

        for (uint256 i = 0; i < stakes[_stakingId][msg.sender].length; i++) {
            Staking storage _staking = stakes[_stakingId][msg.sender][i];
            _earned = _earned.add(
                _staking
                    .amount
                    .mul(plan.apr)
                    .div(10000)
            );

            totalRewards = totalRewards.add(_earned);
            totalRewardsPerPlan[_stakingId] = totalRewardsPerPlan[_stakingId].add(_earned);

            totalRewardsPerWalletPerPlan[_stakingId][msg.sender] = totalRewardsPerWalletPerPlan[_stakingId][msg.sender].add(_earned);

            totalEarnedRewardsPerWallet[msg.sender] += _earned;
        
            _staking.stakeAt = block.timestamp;
        }

        require(_earned > 0, "There is no amount to claim");

        uint256 burnAmount = _earned.mul(_burnRate).div(100);
        IERC20(stakingToken).transfer(BURN_ADDRESS, burnAmount);
        IERC20(stakingToken).transfer(msg.sender, _earned.sub(burnAmount));
    }

Vulnerability type: Business Logic Flaw
HIGH severity: BrahTOPG — The contract zapper does not maintain enough validations, which allows attackers to manipulate the victims' pre-approved funds with fake tokens.. 1. The attacker queried the USDC balance of one of the users 2. Invoke `zapIn` with an attacker-controlled token. 3. The `zapIn` invocation will trigger the `zap` function, transferring the pre-approved USDC tokens from the victim.

Vulnerable code:
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        _status = _NOT_ENTERED;
    }
}

Vulnerability type: Insufficient validation
HIGH severity: Sonne Finance — Compound v2 forks bug. first deposit. https://www.quillaudits.com/blog/hack-analysis/sonne-finance-hack https://www.quillaudits.com/blog/hack-analysis/sonne-finance-hack

Vulnerable code:
function exchangeRateStoredInternal()
        internal
        view
        virtual
        returns (uint256)
    {
        uint256 _totalSupply = totalSupply;
        if (_totalSupply == 0) {
            /*
             * If there are no tokens minted:
             *  exchangeRate = initialExchangeRate
             */
            return initialExchangeRateMantissa;
        } else {
            /*
             * Otherwise:
             *  exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply
             */
            uint256 totalCash = getCashPrior();
            uint256 cashPlusBorrowsMinusReserves = totalCash +
                totalBorrows -
                totalReserves;
            uint256 exchangeRate = (cashPlusBorrowsMinusReserves * expScale) /
                _totalSupply; // <-- vulnerable point

            return exchangeRate;
        }
    }

Vulnerability type: Precision
HIGH severity: OKC Project — The victim contract `MinerPool` requires `extcodesize!=0`(EOA check) before adding an address to `lpRewardProcessor` array to be eligible for rewards. The victim contract `MinerPool` will distribute the rewards regardless of the LP holding time. The attacker leveraged substantial flash loans to borrow a significant amount of USDT and exchanged it for a large quantity of OKC tokens to add liquidity. Additionally, due to the absence of lock-up requirements for LP reward distribution in the OKC project, the hacker promptly withdrew liquidity after receiving rewards, thereby claiming the incentives intended for liquidity providers from the project.. https://lunaray.medium.com/okc-project-hack-analysis-0907312f519b

Vulnerable code:
function addHolder(address adr) external onlyAdmin {
    uint256 size;
    assembly { size := extcodesize(adr) }
    if (size > 0) {
        return;
    }
    if (0 == holderIndex[adr]) {
        if (0 == holders.length || holders[0] != adr) {
            holderIndex[adr] = holders.length;
            holders.push(adr);
        }
    }
}


function processLPReward() public {
if(lastProcessTimestamp + 24 hours > block.timestamp) return;

uint256 lpHolderCount = lpRewardProcessor.getLength();

address pair = lpRewardProcessor.getPair();

uint256 pairTotalSupply = ISwapPair(pair).totalSupply();

uint256 pairTokenBalance = IERC20(ISwapPair(pair).token1()).balanceOf(address(this));
if(lpHolderCount == 0) return;
if(token.balanceOf(address(this)) == 0) return;

for (uint256 i = 0; i < lpHolderCount; i++) {
address _addr = lpRewardProcessor.holders(i);
uint256 _lpBal = IERC20(pair).balanceOf(_addr);

uint256 amount = pairTokenBalance * _lpBal / pairTotalSupply;

token.transfer(_addr, amount * 1 / 100);
}

lastProcessTimestamp = block.timestamp;

Vulnerability type: Flashloans, Reward
HIGH severity: 3913Token — The token uses `pair.reserves()` and `token.balanceOf(pair)` to determine if the current transaction is purchase or sell. However, this could be **manipulated** via sending tokens to the `pair` address and call `skim'. The token will distribute `inviteBonus`  to the `to` address without setting a upper limit for the reward.. https://defimon.xyz/attack/bsc/0x8163738d6610ca32f048ee9d30f4aa1ffdb3ca1eddf95c0eba086c3e936199ed https://www.immunebytes.com/blog/list-of-crypto-hacks-in-the-month-of-november/#Nov_

Vulnerable code:
function _transfer(
    address from,
    address to,
    uint256 amount
) internal returns (bool) {
    require(!_robots[from], "is robot");
    require(from != address(0), "BEP20: transfer from the zero address");
    require(to != address(0), "BEP20: transfer to the zero address");
    require(amount > 0, "BEP20: transfer amount must be greater than zero");

    (bool isAdd, bool isDel) = _isLiquidity(from, to);
    updateTime();
    _burnToken(from);
    _burnToken(to);
    if (_v2Pairs[to] && !isAdd && from != address(this)) {
        burnPairs();
    }

    if (_v2Pairs[from] && !isDel) {
        _inviteBonus(to, amount);
    }
    ...
}

function _inviteBonus(address to, uint256 amount) private {
    if (_users[to].pid != address(0)) {
        uint256 balance_t = _balances[address(_smartVault_invite)];
        if (balance_t == 0) return;

        uint256 bunusAmount = amount.mul(_inviteRate).div(RBASE);
        bunusAmount = bunusAmount > balance_t ? balance_t : bunusAmount;

        _smartVault_invite.transfer(address(this), _users[to].pid, bunusAmount);
    }
}

Vulnerability type: ERC20, Flashloans, Reward
HIGH severity: LPC — Incorrect recipient balance check, did not check sender!=recipient in transfer. Increase directly on the recipientAmount to recipient, deduct sender balance incorrectly.. Increase directly on the recipientAmount to recipient, deduct sender balance incorrectly.

Vulnerable code:
function _transfer(
    // ... other parameters
) internal {
    totalHolders = totalHolders_;

    _balances[sender] = senderBalance.sub(amount);
    _balances[recipient] = recipientBalance.add(recipientAmount);
    emit Transfer(sender, recipient, recipientAmount);

    _afterTokenTransfer(sender, recipient, amount);
}

Vulnerability type: ERC20, Flashloans, Insufficient validation
HIGH severity: Lodestar — FlashLoan price manipulation - Incorrect logic in GLPOracle.
The root cause is attributed to the construction of the Lodestar GLPOracle and how it obtained the price of plvGLP tokens. The GLPOracle failed to consider the impact of a user calling the donate() function on the GlpDepositor contract. This action inflated the assets of the GlpDepositor contract, consequently affecting the oracle-delivered price of the plvGLP token. As a result, the price reported by the GLPOracle became inaccurate due to the improper handling of the donation mechanism, leading to the vulnerability exploited by malicious users.. https://twitter.com/SolidityFinance/status/1601684150456438784 https://blog.lodestarfinance.io/post-mortem-summary-13f5fe0bb336

Vulnerable code:
function getPlvGLPPrice() public view returns (uint256) {
        uint256 exchangeRate = getPlutusExchangeRate();

        uint256 glpPrice = getGLPPrice();

        uint256 price = (exchangeRate * glpPrice) / BASE;

        return price;
    }
function getPlutusExchangeRate() public view returns (uint256) {
        //retrieve total assets from plvGLP contract
        uint256 totalAssets = plvGLPInterface(plvGLP).totalAssets();

        //retrieve total supply from plvGLP contract
        uint256 totalSupply = EIP20Interface(plvGLP).totalSupply();

        //plvGLP/GLP Exchange Rate = Total Assets / Total Supply
        uint256 exchangeRate = (totalAssets * BASE) / totalSupply;

        return exchangeRate;
    }
 
function donate(uint256 _assets) external {
sGLP.safeTransferFrom(msg.sender, staker, _assets);
ITokenMinter(minter).mint(vault, _assets);
  }

Vulnerability type: Flashloans, Incorrect logic, Price Manipulation
HIGH severity: HackDao — Incorrect logic in _transfer  function of token contract.Cause Uniswap pair can be reduced without any swap, so attacker can do price manipulation. Once imbalance in the pair, attacker can call skim() to get profit.. Cause Uniswap pair can be reduced without any swap, so attacker can do price manipulation. Once imbalance in the pair, attacker can call skim() to get profit.

Vulnerable code:
function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal override virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];

        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        uint256 actualAmount = amount;

        if(parentAddress[recipient] == address(0) && recipient != uniswapV2Pair){
            if(sender == uniswapV2Pair){
                parentAddress[recipient] = _defaultAddress;
            }else{
                parentAddress[recipient] = sender;
            }
        }

        if(!isWhiteListed(sender) && !isWhiteListed(recipient)){
            
            uint256 fee = calculationFeeNum(amount,_feeRatio);
            //sell
            if(recipient == uniswapV2Pair){
                require(senderBalance >= amount.add(fee), "ERC20: There are not enough charges for the account balance");
                unchecked {
                    _balances[sender] -= fee;
                }
            }else{
                actualAmount = amount - fee;
            }

Vulnerability type: DAO, Flashloans, skim
HIGH severity: ANCH — insufficient validation , get rewards over skim(). if it supports skim(), the token transfer does not check if recipient and sender are the same, any reward, factor and balance change in _transfer() function, then you are vulnerable for the attack.. if it supports skim(), the token transfer does not check if recipient and sender are the same, any reward, factor and balance change in _transfer() function, then you are vulnerable for the attack.

The wild attack is on fire.

[$UPS](https://twitter.com/search?q=%24UPS&src=cashtag_click)
[$ANCH](ht

Vulnerable code:
//this method is responsible for taking all fee, if takeFee is true
    function _transfer( //vulnerable point - recipient and sender can the same
        address sender,
        address recipient,
        uint256 tAmount
    ) private {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(tAmount > 0, "Transfer amount must be greater than zero");
        // Insufficient validation. sender and recipient can be same.
        
	if(sender == uniswapV2Pair) {
            _tokenBuyTransferReward(sender, recipient, tAmount);
        } else if(recipient == uniswapV2Pair) {
            _tokenSellTransferReward(sender, recipient, tAmount);
        } else{

            uint256 currentRate = _getRate();
            uint256 rAmount = tAmount.mul(currentRate);
            _rOwned[sender] = _rOwned[sender].sub(rAmount);
            _rOwned[recipient] = _rOwned[recipient].add(rAmount);
            
            emit Transfer(sender, recipient, tAmount);
        }

Vulnerability type: ERC20, Flashloans, Insufficient validation, Reward
HIGH severity: CompounderFinance — Fluctuations in the amount of funds available for exchange due to changes in the proportions of the liquidity pool.. https://twitter.com/numencyber/status/1666346419702362112

Vulnerable code:
function deposit() public {
    uint _want = IERC20(want).balanceOf(address(this));
    if (_want > 0) {
        IERC20(want).safeApprove(y, 0);
        IERC20(want).safeApprove(y, _want);
        yERC20(y).deposit(_want);
    }
    uint _y = IERC20(y).balanceOf(address(this));
    if (_y > 0) {
        IERC20(y).safeApprove(curve, 0);
        IERC20(y).safeApprove(curve, _y);
        ICurveFi(curve).add_liquidity(_y, 0, 0, 0);
    }
    uint _ycrv = IERC20(ycrv).balanceOf(address(this));
    if (_ycrv > 0) {
        IERC20(ycrv).safeApprove(yycrv, 0);
        IERC20(ycrv).safeApprove(yycrv, _ycrv);
        yERC20(yycrv).deposit(_ycrv);
    }
}

Vulnerability type: Flashloans, Price Manipulation
HIGH severity: BEGO — Insufficient validation. None

Vulnerable code:
modifier isSigned(
        string memory _txHash,
        uint256 _amount,
        bytes32[] memory _r,
        bytes32[] memory _s,
        uint8[] memory _v
    ) {
        require(checkSignParams(_r, _s, _v), "bad-sign-params");
        bytes32 _hash = keccak256(abi.encodePacked(bsc, msg.sender, _txHash, _amount));
        address[] memory _signers = new address[](_r.length); //vulnerable point
        for (uint8 i = 0; i < _r.length; i++) {
            _signers[i] = ecrecover(_hash, _v[i], _r[i], _s[i]);
        }

        require(isSigners(_signers), "bad-signers");
        _;
    }

    function isSigners(address[] memory _signers) public view returns (bool){
        for (uint8 i = 0; i < _signers.length; i++) {  //vulnerable point
            if (!_containsSigner(_signers[i])) {
                return false;
            }
        }
        return true;  // null data will return true 
    }

    function mint(
        uint256 _amount,
        string memory _txHash,
        address _receiver,
        bytes32[] memory _r,
        bytes32[] memory _s,
        uint8[] memory _v
    ) isSigned(_txHash, _amount, _r, _s, _v) external returns (bool){ //trace isSigned
        require(!txHashes[_txHash], "tx-hash-used");
        txHashes[_txHash] = true;

        _mint(_receiver, _amount);
        return true;
    }

Vulnerability type: Insufficient validation