Farseen0/scar-pairs huggingface dataset:
MEDIUM severity: Excessive authority issue. In the ROTL contract, the DEFAULT_ADMIN_ROLE can set the minter role, and the minter role can mint ERC721A tokens arbitrarily.

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

pragma solidity ^0.8.4;

import "./ERC721A.sol";
import "./extensions/ERC721ABurnable.sol";
import "./extensions/ERC721AQueryable.sol";
import "./access/AccessControlEnumerable.sol";
import "./utils/math/SafeMath.sol";

contract ROTL is AccessControlEnumerable, ERC721A, ERC721ABurnable, ERC721AQueryable {
    using SafeMath for uint256;

    event SetBaseTokenURI(string uri);

    string private _baseTokenURI;
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor() ERC721A("Ruler of the Land", "ROTL") {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
    }

    function getFaction(uint256 id) external pure returns (uint256) {
        if (id < 5000) {
            return 1;
        } else if (id < 10000) {
            return 2;
        } else if (id < 15000) {
            return 3;
        } else if (id < 25000) {
            return 4;
        } else if (id < 35000) {
            return 5;
        }
        return 0;
    }

    function mint(uint256 faction, address to, uint256 quantity) external onlyRole(MINTER_ROLE) {
        if (faction == 1) {
            // darkstorm bringers
            require (totalSupply().add(quantity) <= 5000, "totalSupply().add(quantity) <= 5000");
        } else if (faction == 2) {
            // righteous faction
            require (totalSupply().add(quantity) <= 10000, "totalSupply().add(quantity) <= 10000");
        } else if (faction == 3) {
            // cult faction
            require (totalSupply().add(quantity) <= 15000, "totalSupply().add(quantity) <= 15000");
        } else if (faction == 4) {
            // the four outworld Hordes
            require (totalSupply().add(quantity) <= 25000, "totalSupply().add(quantity) <= 25000");
        } else {
            // sanctuary of the sword
            require (totalSupply().add(quantity) <= 35000, "totalSupply().add(quantity) <= 35000");
        }
        // _safeMint's second argument now takes in a quantity, not a tokenId.
        _safeMint(to, quantity);
    }

    function addMinter(address minter) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setupRole(MINTER_ROLE, minter);
    }

    function setBaseTokenURI(string memory uri) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _baseTokenURI = uri;
        emit SetBaseTokenURI(uri);
    }

    function _baseURI() internal view override returns (string memory) {
        return _baseTokenURI;
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(AccessControlEnumerable, ERC721A)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}


Vulnerability type: CWE-284|CWE-269|CWE-267
MEDIUM severity: Business logic flaws. The swapCoinForCrosschainCoin function will call cerc20.depositTo with msg.sender as the CrosschainCoinRouter contract.

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

pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./CrosschainERC20.sol";

interface WrappedCoin {
    function deposit() external payable;

    function withdraw(uint256) external;
}

contract CrosschainCoinRouter {
    using SafeERC20 for ERC20;

    WrappedCoin public wrappedCoin;
    CrosschainERC20 public cerc20;

    constructor(CrosschainERC20 _cerc20) {
        ERC20 ct = _cerc20.coToken();
        cerc20 = _cerc20;
        ct.safeApprove(address(cerc20), type(uint256).max);
        wrappedCoin = WrappedCoin(address(ct));
    }

    receive() external payable {}

    function resetAllowance() public {
        ERC20 wc = ERC20(address(wrappedCoin));
        uint256 allowance = wc.allowance(address(this), address(cerc20));
        if (allowance != type(uint256).max) {
            wc.safeIncreaseAllowance(address(cerc20), type(uint256).max - allowance);
        }
    }

    function swapCoinForCrosschainCoin(uint256 _amount) public payable {
        require(msg.value == _amount, "incorrect amount value");
        wrappedCoin.deposit{value: _amount}();
        cerc20.depositTo(msg.sender, _amount);
    }

    function swapCrosschainCoinForCoin(uint256 _amount) public {
        ERC20(cerc20).safeTransferFrom(msg.sender, address(this), _amount);
        cerc20.withdraw(_amount);
        wrappedCoin.withdraw(_amount);
        payable(msg.sender).transfer(_amount);
    }

    function swapWrappedCoinForCrosschainCoin(uint256 _amount) public {
        ERC20(address(wrappedCoin)).safeTransferFrom(msg.sender, address(this), _amount);
        cerc20.depositTo(msg.sender, _amount);
    }

    function swapCrosschainCoinForWrappedCoin(uint256 _amount) public {
        ERC20(cerc20).safeTransferFrom(msg.sender, address(this), _amount);
        cerc20.withdrawTo(msg.sender, _amount);
    }

    function swapCoinForWrappedCoin(uint256 _amount) public payable {
        require(msg.value == _amount, "incorrect amount value");
        wrappedCoin.deposit{value: _amount}();
        ERC20(address(wrappedCoin)).safeTransfer(msg.sender, _amount);
    }

    function swapWrappedCoinForCoin(uint256 _amount) public {
        ERC20(address(wrappedCoin)).safeTransferFrom(msg.sender, address(this), _amount);
        wrappedCoin.withdraw(_amount);
        payable(msg.sender).transfer(_amount);
    }
}


Vulnerability type: CWE-284|CWE-285|CWE-862
HIGH severity: Bug in read() function returns the wrong ethUsd18 rate. Function read() always returns the wrong `ethUsd18` rate due to a conversion bug.

Vulnerable code:
pragma solidity 0.6.6;

// SPDX-License-Identifier: Unlicensed

interface IUniswap {
    function getReserves() external view returns(uint112, uint112, uint32);
}

interface IHOracle {
   function read() external view returns(uint ethUsd18); 
}

contract HOracle is IHOracle {

    IUniswap uniswap = IUniswap(0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc);
    uint constant PRECISION = 10 ** 18;
    uint constant UNISWAP_SHIFT = 10 ** 12;
    
    function read() public view override returns(uint ethUsd18) {
        (uint112 uniswapReserve0, uint112 uniswapReserve1, /*uint32 timeStamp*/) = uniswap.getReserves();
        ethUsd18 = (uint(uniswapReserve0) * PRECISION * UNISWAP_SHIFT) / (uniswapReserve1);
    }
}


Vulnerability type: CWE-682
HIGH severity: HodlDex’s admin can obtain HCETHUSD at close to zero cost. HodlDex’s admin can temporarily provide a malicious Oracle via the adminSetOracle() function, potentially allowing them to obtain `HCETHUSD` at close to zero cost.

Vulnerable code:
pragma solidity 0.6.6;

// SPDX-License-Identifier: Unlicensed

import "./HodlDexV0.sol";

contract HodlDex is HodlDexV0 {
    
    function withdrawEth(uint amount) external override ifRunning {
        emit UserWithdrawEth(msg.sender, amount);
        balance.sub(ETH_ASSET, msg.sender, amount, 0);
        (bool success, /* bytes memory data */) = msg.sender.call{value:amount}("");
        require(success, "rejected by receiver");
    }
    
    function initResetUser(address userAddr) external override onlyMigration {
        emit UserUninitialized(msg.sender, userAddr);
        balance.add(HODL_ASSET, address(this), balance.balanceOf(HODL_ASSET, userAddr), 0);
        balance.sub(HODL_ASSET, userAddr, balance.balanceOf(HODL_ASSET, userAddr), 0);
        balance.sub(ETH_ASSET, userAddr, balance.balanceOf(ETH_ASSET, userAddr), 0);
        if(balance.balanceOf(ETH_ASSET, userAddr) > 0) {
            (bool success, /* bytes memory data */) = msg.sender.call{ value: balance.balanceOf(ETH_ASSET, userAddr) }("");
            require(success, "rejected by receiver");
        }
    }       
}

Vulnerability type: CWE-284
HIGH severity: L1_ETH_Bridge.sol: _transferFromBridge() can be griefed. The function _transferFromBridge() sends ETH out and reverts on failure, which may cause permanent failure of certain kinds of resolveChallenge() flows.

Vulnerable code:
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

import "./L1_Bridge.sol";

/**
 * @dev A L1_Bridge that uses an ETH as the canonical token
 */

contract L1_ETH_Bridge is L1_Bridge {
    constructor (address[] memory bonders) public L1_Bridge(bonders) {}

    /* ========== Override Functions ========== */

    function _transferFromBridge(address recipient, uint256 amount) internal override {
        (bool success, ) = recipient.call{value: amount}(new bytes(0));
        require(success, 'L1_ERC20_BRG: ETH transfer failed');
    }

    function _transferToBridge(address /*from*/, uint256 amount) internal override {
        require(msg.value == amount, "L1_ERC20_BRG: Value does not match amount");
    }
}


Vulnerability type: CWE-703|CWE-755
HIGH severity: Price feed oracle fake timestamp. The MoC oracles do not provide the last update timestamp, which can result in Sovryn components operating with a potentially outdated exchange rate.

Vulnerable code:
pragma solidity 0.4.26;

import "./interfaces/IConsumerPriceOracle.sol";
import "./Owned.sol";

interface Medianizer {
	function peek() external view returns (bytes32, bool);
}

contract MocBTCToUSDOracle is IConsumerPriceOracle, Owned {
	address public mocOracleAddress;

	event SetMoCOracleAddress(address indexed mocOracleAddress, address changerAddress);

	/**
	 * @dev initializes a ne MoC oracle
	 *
	 * @param _mocOracleAddress MoC oracle address
	 */
	constructor(address _mocOracleAddress) public {
		setMoCOracleAddress(_mocOracleAddress);
	}

	/**
	 * @dev returns the USD/BTC rate.
	 *
	 * @return MoC medianizer rate
	 */
	function latestAnswer() external view returns (int256) {
		(bytes32 value, bool hasValue) = Medianizer(mocOracleAddress).peek();
		require(hasValue, "Doesn't has value");
		return int256(value);
	}

	/**
	 * @dev returns the USD/BTC update time.
	 *
	 * @return always returns current block's timestamp
	 */
	function latestTimestamp() external view returns (uint256) {
		return now; // MoC oracle doesn't return update timestamp
	}

	/**
	 * @dev set MoC oracle address
	 *
	 * @param _mocOracleAddress MoC oracle address
	 */
	function setMoCOracleAddress(address _mocOracleAddress) public ownerOnly {
		require(_mocOracleAddress != address(0), "_mocOracleAddress shall not be zero address");
		mocOracleAddress = _mocOracleAddress;
		emit SetMoCOracleAddress(mocOracleAddress, msg.sender);
	}
}


Vulnerability type: CWE-435
MEDIUM severity: Logical issue in claim function. msg.value is not strictly checked in claim() function

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

contract Claim {

  event Log(address indexed pool_, uint256 indexed policyIndex_, string notes_);

  function file(address pool_, uint256 policyIndex_, string calldata notes_) external {
    emit Log(pool_, policyIndex_, notes_);
  }
}


Vulnerability type: CWE-20
HIGH severity: Mint PerpetualYieldTokens for free by self-transfer. The PYT.transfer and transferFrom functions operate on cached balance values, allowing an attacker to mint PYT tokens for free by self-transferring.

Vulnerable code:
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.4;

import {Gate} from "./Gate.sol";
import {BaseERC20} from "./lib/BaseERC20.sol";

/// @title PerpetualYieldToken
/// @author zefram.eth
/// @notice The ERC20 contract representing perpetual yield tokens
contract PerpetualYieldToken is BaseERC20 {
    /// -----------------------------------------------------------------------
    /// Constructor
    /// -----------------------------------------------------------------------

    constructor(Gate gate_, address vault_)
        BaseERC20(
            gate_.perpetualYieldTokenName(vault_),
            gate_.perpetualYieldTokenSymbol(vault_),
            gate_,
            vault_
        )
    {}

    /// -----------------------------------------------------------------------
    /// ERC20 overrides
    /// -----------------------------------------------------------------------

    function transfer(address to, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        // load balances to save gas
        uint256 fromBalance = balanceOf[msg.sender];
        uint256 toBalance = balanceOf[to];

        // call transfer hook
        gate.beforePerpetualYieldTokenTransfer(
            msg.sender,
            to,
            amount,
            fromBalance,
            toBalance
        );

        // do transfer
        balanceOf[msg.sender] = fromBalance - amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] = toBalance + amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        // load balances to save gas
        uint256 fromBalance = balanceOf[from];
        uint256 toBalance = balanceOf[to];

        // call transfer hook
        gate.beforePerpetualYieldTokenTransfer(
            from,
            to,
            amount,
            fromBalance,
            toBalance
        );

        // update allowance
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max)
            allowance[from][msg.sender] = allowed - amount;

        // do transfer
        balanceOf[from] = fromBalance - amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] = toBalance + amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }
}


Vulnerability type: CWE-284|CWE-285|CWE-862
HIGH severity: Failed transfer may be overlooked due to lack of contract existence check. The pool fails to check that a contract exists and assumes failed transactions involving destructed tokens are successful.

Vulnerable code:
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;

import '../token/IERC20.sol';

library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'STE');
    }
}

Vulnerability type: CWE-703|CWE-754
MEDIUM severity: M01. Mishandled Edge Case. If-else control statements are structured in a manner that can lead to unintended execution under certain conditions.

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

library FixedPoint {
    // range: [0, 2**112 - 1]
    // resolution: 1 / 2**112
    struct uq112x112 {
        uint224 _x;
    }

    // returns a uq112x112 which represents the ratio of the numerator to the denominator
    // equivalent to encode(numerator).div(denominator)
    function fraction(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) {
        require(denominator > 0, "FixedPoint: DIV_BY_ZERO");
        return uq112x112((uint224(numerator) << 112) / denominator);
    }

    // decode a uq112x112 into a uint with 18 decimals of precision
    function decode112with18(uq112x112 memory self) internal pure returns (uint256) {
        // we only have 256 - 224 = 32 bits to spare, so scaling up by ~60 bits is dangerous
        // instead, get close to:
        //  (x * 1e18) >> 112
        // without risk of overflowing, e.g.:
        //  (x) / 2 ** (112 - lg(1e18))
        return uint256(self._x) / 5192296858534827;
    }
}

// library with helper methods for oracles that are concerned with computing average prices
library PancakeOracleLibrary {
    using FixedPoint for *;

    // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1]
    function currentBlockTimestamp() internal view returns (uint32) {
        return uint32(block.timestamp % 2 ** 32);
    }

    // produces the cumulative price using counterfactuals to save gas and avoid a call to sync.
    function currentCumulativePrices(
        address pair
    ) internal view returns (uint256 price0Cumulative, uint256 price1Cumulative, uint32 blockTimestamp) {
        blockTimestamp = currentBlockTimestamp();
        price0Cumulative = IPancakePair(pair).price0CumulativeLast();
        price1Cumulative = IPancakePair(pair).price1CumulativeLast();

        // if time has elapsed since the last update on the pair, mock the accumulated price values
        (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IPancakePair(pair).getReserves();
        if (blockTimestampLast != blockTimestamp) {
            unchecked {
                // subtraction overflow is desired
                uint32 timeElapsed = blockTimestamp - blockTimestampLast;
                // addition overflow is desired
                // counterfactual
                price0Cumulative += uint256(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed;
                // counterfactual
                price1Cumulative += uint256(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed;
            }
        }
    }
}

interface IPancakePair {
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);
}


Vulnerability type: CWE-691|CWE-670
HIGH severity: Use tx.origin for authentication is vulnerable to phishing. Vulnerable to phishing attacks.

Vulnerable code:
/*
 * Copyright ConsenSys AG.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
pragma solidity >=0.7.0 <0.9.0;

// compile with:
// solc EventEmitter.sol --bin --abi --optimize --overwrite -o .
// then create web3j wrappers with:
// web3j solidity generate -b ./generated/EventEmitter.bin -a ./generated/EventEmitter.abi -o ../../../../../ -p org.hyperledger.besu.tests.web3j.generated
contract EventEmitter {
    address owner;
    event stored(address _to, uint _amount);
    address _sender;
    uint _value;

    constructor() {
        owner = msg.sender;
    }

    function store(uint _amount) public {
        emit stored(msg.sender, _amount);
        _value = _amount;
        _sender = msg.sender;
    }

    function value()  view public  returns (uint) {
        return _value;
    }

    function sender() view public returns (address) {
        return _sender;
    }
}

Vulnerability type: CWE-284|CWE-346
HIGH severity: Lack of chainID validation allows signatures to be re-used across forks. Signatures used in calls to permit do not account for chainsplits.

Vulnerable code:
// SPDX-License-Identifier: GPL-3.0-or-later
// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/cryptography/ECDSA.sol";

import "../interfaces/IERC2612.sol";

/**
 * @dev Extension of {ERC20} that allows token holders to use their tokens
 * without sending any transactions by setting {IERC20-allowance} with a
 * signature using the {permit} method, and then spend them via
 * {IERC20-transferFrom}.
 *
 * The {permit} signature mechanism conforms to the {IERC2612} interface.
 */
abstract contract ERC20Permit is ERC20, IERC2612 {
    mapping (address => uint256) public override nonces;

    bytes32 public immutable PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 public immutable DOMAIN_SEPARATOR;

    constructor() internal {
        uint256 chainId;
        assembly {
            chainId := chainid()
        }

        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                keccak256(bytes(name())),
                keccak256(bytes("1")),
                chainId,
                address(this)
            )
        );
    }

    /**
     * @dev See {IERC2612-permit}.
     *
     * In cases where the free option is not a concern, deadline can simply be
     * set to uint(-1), so it should be seen as an optional parameter
     */
    function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {
        require(deadline >= block.timestamp, "ERC20Permit: expired deadline");

        bytes32 hashStruct = keccak256(
            abi.encode(
                PERMIT_TYPEHASH,
                owner,
                spender,
                amount,
                nonces[owner]++,
                deadline
            )
        );

        bytes32 hash = keccak256(
            abi.encodePacked(
                '\x19\x01',
                DOMAIN_SEPARATOR,
                hashStruct
            )
        );

        address signer = ecrecover(hash, v, r, s);
        require(
            signer != address(0) && signer == owner,
            "ERC20Permit: invalid signature"
        );

        _approve(owner, spender, amount);
    }
}


Vulnerability type: CWE-693|CWE-345|CWE-347