Farseen0/scar-pairs huggingface dataset:
HIGH severity: Best Practice Violation. Using an outdated version of AccessControl.sol contract.

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

import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

abstract contract AccessControl is Context {
    struct RoleData {
        mapping (address => bool) members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    function hasRole(bytes32 role, address account) public view returns (bool) {
        return _roles[role].members[account];
    }

    function _checkRole(bytes32 role, address account) internal view {
        if(!hasRole(role, account)) {
            revert(string(abi.encodePacked(
                "AccessControl: account ",
                Strings.toHexString(uint160(account), 20),
                " is missing role ",
                Strings.toHexString(uint256(role), 32)
            )));
        }
    }

    function getRoleAdmin(bytes32 role) public view returns (bytes32) {
        return _roles[role].adminRole;
    }

    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    function renounceRole(bytes32 role, address account) public virtual {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        emit RoleAdminChanged(role, getRoleAdmin(role), adminRole);
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

Vulnerability type: CWE-710
MEDIUM severity: M01. Copy Of Well Known Contract. Using a copy of well-known contracts instead of importing them directly from source.

Vulnerable code:
//           ▄▄
//           ▀██▄    ██        ╔══
//   ▄▄▄▄▄▄▄▄  ▀██▄  ██        ║
//   ▀▀▀▀▀▀▀▀    ▀▀  ██           Octavia
//      ▄▄           ██   ▄▄      by Octavia Laboratories
//    ▄██▀              ▄██▀ 
//  ▄██▀              ▄██▀        The Superhuman AI Assistant
//  ▀▀  ▄▄            ▀▀          
//      ██                        octavia.one
//      ██   ▄▄   ████████        discord.gg/octavia
//      ██   ▀██▄              ║
//      ▀▀     ▀██▄            ╚══
//               ▀▀

pragma solidity ^0.8.9;

import "./@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
import "./@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";

contract Octavia is ERC20, ERC20Permit, ERC20Votes {
    constructor() ERC20("Octavia", "VIA") ERC20Permit("Octavia") {
        _mint(msg.sender, 100000000 * 10 ** decimals());
    }

    // The following functions are overrides required by Solidity.

    function _afterTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._afterTokenTransfer(from, to, amount);
    }

    function _mint(address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._mint(to, amount);
    }

    function _burn(address account, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._burn(account, amount);
    }
}


Vulnerability type: CWE-710|CWE-477
MEDIUM severity: Verify pool legitimacy. The constructor in OverlayV1UniswapV3Factory.sol and OverlayV1UniswapV3Feed.sol only does a partial check to see if the pool corresponds to the supplied tokens.

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

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "../../interfaces/feeds/uniswapv3/IOverlayV1UniswapV3FeedFactory.sol";

import "../OverlayV1FeedFactory.sol";
import "./OverlayV1UniswapV3Feed.sol";

contract OverlayV1UniswapV3Factory is IOverlayV1UniswapV3FeedFactory, OverlayV1FeedFactory {
    address public immutable ovlWethPool;
    address public immutable ovl;

    // registry of feeds; for a given (pool, base, quote, amount) pair, returns associated feed
    mapping(address => mapping(address => mapping(address => mapping(uint128 => address))))
        public getFeed;

    constructor(
        address _ovlWethPool,
        address _ovl,
        uint256 _microWindow,
        uint256 _macroWindow
    ) OverlayV1FeedFactory(_microWindow, _macroWindow) {
        ovlWethPool = _ovlWethPool;
        ovl = _ovl;
    }

    /// @dev deploys a new feed contract
    /// @return feed_ address of the new feed
    function deployFeed(
        address marketPool,
        address marketBaseToken,
        address marketQuoteToken,
        uint128 marketBaseAmount
    ) external returns (address feed_) {
        require(
            getFeed[marketPool][marketBaseToken][marketQuoteToken][marketBaseAmount] == address(0),
            "OVLV1: feed already exists"
        );

        // Use the CREATE2 opcode to deploy a new Feed contract.
        // Will revert if feed which accepts (marketPool, marketBaseToken, marketQuoteToken,
        // marketBaseAmount) in its constructor has already been deployed since salt would be the
        // same and can't deploy with it twice.
        feed_ = address(
            new OverlayV1UniswapV3Feed{
                salt: keccak256(
                    abi.encode(marketPool, marketBaseToken, marketQuoteToken, marketBaseAmount)
                )
            }(
                marketPool,
                ovlWethPool,
                ovl,
                marketBaseToken,
                marketQuoteToken,
                marketBaseAmount,
                microWindow,
                macroWindow
            )
        );

        // store feed registry record for (marketPool, marketBaseToken, marketQuoteToken) combo
        // and record address as deployed feed
        getFeed[marketPool][marketBaseToken][marketQuoteToken][marketBaseAmount] = feed_;
        isFeed[feed_] = true;
        emit FeedDeployed(msg.sender, feed_);
    }
}


Vulnerability type: CWE-703|CWE-754
HIGH severity: TransferAndCall does not restrict transfers to stakingContract. transferAndCall does not restrict transfers to the staking contract, which can be exploited.

Vulnerable code:
pragma solidity 0.4.24;

import "../ERC677BridgeTokenRewardable.sol";

contract ERC677BridgeTokenRewardableMock is ERC677BridgeTokenRewardable {
    uint256 private _blockTimestamp;

    constructor(string _name, string _symbol, uint8 _decimals, uint256 _chainId)
        public
        ERC677BridgeTokenRewardable(_name, _symbol, _decimals, _chainId)
    {
        // solhint-disable-previous-line no-empty-blocks
    }

    function setBlockRewardContractMock(address _blockRewardContract) public {
        blockRewardContract = _blockRewardContract;
    }

    function setStakingContractMock(address _stakingContract) public {
        stakingContract = _stakingContract;
    }

    function setNow(uint256 _timestamp) public {
        _blockTimestamp = _timestamp;
    }

    function _now() internal view returns (uint256) {
        return _blockTimestamp != 0 ? _blockTimestamp : now;
    }

}


Vulnerability type: CWE-284
MEDIUM severity: transferOwnership + claimOwnership. Perhaps it will make sense to implement the transferOwnership + claimOwnership scheme instead of just transferOwnership without proper knowledge.

Vulnerable code:
pragma solidity 0.4.24;

import "./EternalStorage.sol";
import "./OwnedUpgradeabilityProxy.sol";

/**
 * @title EternalStorageProxy
 * @dev This proxy holds the storage of the token contract and delegates every call to the current implementation set.
 * Besides, it allows to upgrade the token's behaviour towards further implementations, and provides basic
 * authorization control functionalities
 */
// solhint-disable-next-line no-empty-blocks
contract EternalStorageProxy is EternalStorage, OwnedUpgradeabilityProxy {}


Vulnerability type: CWE-284|CWE-282
HIGH severity: Incorrect grace period could result in denial of service. Setting the grace period parameter too high could result in a denial-of-service condition.

Vulnerable code:
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.7;

import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol';
import {IPriceOracleSentinel} from '../../interfaces/IPriceOracleSentinel.sol';
import {ISequencerOracle} from '../../interfaces/ISequencerOracle.sol';

/**
 * @title PriceOracleSentinel
 * @author Aave
 * @notice It validates if operations are allowed depending on the PriceOracle health.
 * @dev After a PriceOracle downtime, once it gets up, users can make their positions healthy during a grace period.
 */
contract PriceOracleSentinel is IPriceOracleSentinel {
  IPoolAddressesProvider public _addressesProvider;
  ISequencerOracle public _oracle;
  uint256 public _gracePeriod;

  /**
   * @notice Constructor
   * @param provider The address of the PoolAddressesProvider
   * @param oracle The address of the SequencerOracle
   * @param gracePeriod The duration of the grace period in seconds
   */
  constructor(
    IPoolAddressesProvider provider,
    ISequencerOracle oracle,
    uint256 gracePeriod
  ) {
    _addressesProvider = provider;
    _oracle = oracle;
    _gracePeriod = gracePeriod;
  }

  /// @inheritdoc IPriceOracleSentinel
  function isBorrowAllowed() public view override returns (bool) {
    return _isUpAndGracePeriodPassed();
  }

  /// @inheritdoc IPriceOracleSentinel
  function isLiquidationAllowed() public view override returns (bool) {
    return _isUpAndGracePeriodPassed();
  }

  function _isUpAndGracePeriodPassed() internal view returns (bool) {
    (bool isDown, uint256 timestampGotUp) = _oracle.latestAnswer();
    return !isDown && block.timestamp - timestampGotUp > _gracePeriod;
  }
}


Vulnerability type: CWE-664|CWE-400|CWE-770
MEDIUM severity: getAmountOut underestimates outputs leading to losses. When computing the output, the getAmountOut performs a bisection, but it returns any root of the function, not the lowest root.

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

/// @dev Thrown when the lower bound is greater than the upper bound.
error BisectionLib_InvalidBounds(uint256 lower, uint256 upper);
/// @dev Thrown when the result of the function `fx` for each input, `upper` and `lower`, is the same sign.
error BisectionLib_RootOutsideBounds(uint256 lower, uint256 upper);

/**
 * @notice
 * The function `fx` must be continuous and monotonic.
 *
 * @dev
 * Bisection is a method of finding the root of a function.
 * The root is the point where the function crosses the x-axis.
 *
 * @param args The arguments to pass to the function `fx`.
 * @param lower The lower bound of the root to find.
 * @param upper The upper bound of the root to find.
 * @param epsilon The maximum distance between the lower and upper results.
 * @param maxIterations The maximum amount of loop iterations to run.
 * @param fx The function to find the root of.
 * @return root The root of the function `fx`.
 */
function bisection(
    bytes memory args,
    uint256 lower,
    uint256 upper,
    uint256 epsilon,
    uint256 maxIterations,
    function(bytes memory,uint256) pure returns (int256) fx
) pure returns (uint256 root) {
    if (lower > upper) revert BisectionLib_InvalidBounds(lower, upper);
    // Passes the lower and upper bounds to the optimized function.
    // Reverts if the optimized function `fx` returns both negative or both positive values.
    // This means that the root is not between the bounds.
    // The root is between the bounds if the product of the two values is negative.
    int256 lowerOutput = fx(args, lower);
    int256 upperOutput = fx(args, upper);
    if (lowerOutput * upperOutput > 0) {
        revert BisectionLib_RootOutsideBounds(lower, upper);
    }

    // Distance is optimized to equal `epsilon`.
    uint256 distance = upper - lower;

    uint256 iterations; // Bounds the amount of loops to `maxIterations`.
    do {
        // Bisection uses the point between the lower and upper bounds.
        // The `distance` is halved each iteration.
        root = (lower + upper) / 2;

        int256 output = fx(args, root);

        // If the product is negative, the root is between the lower and root.
        // If the product is positive, the root is between the root and upper.
        if (output * lowerOutput <= 0) {
            upper = root; // Set the new upper bound to the root because we know its between the lower and root.
        } else {
            lower = root; // Set the new lower bound to the root because we know its between the upper and root.
            lowerOutput = output; // root function value becomes new lower output value
        }

        // Update the distance with the new bounds.
        distance = upper - lower;

        unchecked {
            iterations++; // Increment the iterator.
        }
    } while (distance > epsilon && iterations < maxIterations);
}


Vulnerability type: CWE-682
HIGH severity: Reserves Not Always Updated In onJoinPool(). Reserves not updated in certain conditions

Vulnerable code:
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;

import { Authorizer } from "@balancer-labs/v2-vault/contracts/Authorizer.sol";
import { Vault } from "@balancer-labs/v2-vault/contracts/Vault.sol";
import { Space } from "../lib/v1-space/src/Space.sol";
import { SpaceFactory } from "../lib/v1-space/src/SpaceFactory.sol";

Vulnerability type: CWE-664|CWE-372
HIGH severity: ALLOWED_PROXY permission control attack. ALLOWED_PROXY role can transfer authorized contract amounts.

Vulnerable code:
/*

    Copyright 2021 DODO ZOO.
    SPDX-License-Identifier: Apache-2.0

*/

pragma solidity 0.6.9;

import {IERC721} from "../intf/IERC721.sol";
import {IERC1155} from "../intf/IERC1155.sol";
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";

/**
 * @title DODONFTApprove
 * @author DODO Breeder
 *
 * @notice Handle NFT authorizations in DODO platform
 */
contract DODONFTApprove is InitializableOwnable {
    
    // ============ Storage ============
    uint256 private constant _TIMELOCK_DURATION_ = 3 days;
    mapping (address => bool) public _IS_ALLOWED_PROXY_;
    uint256 public _TIMELOCK_;
    address public _PENDING_ADD_DODO_PROXY_;

    // ============ Events ============
    event AddDODOProxy(address dodoProxy);
    event RemoveDODOProxy(address oldProxy);

    // ============ Modifiers ============
    modifier notLocked() {
        require(
            _TIMELOCK_ <= block.timestamp,
            "AddProxy is timelocked"
        );
        _;
    }

    function init(address owner, address[] memory proxies) external {
        initOwner(owner);
        for(uint i = 0; i < proxies.length; i++) 
            _IS_ALLOWED_PROXY_[proxies[i]] = true;
    }

    function unlockAddProxy(address newDodoProxy) external onlyOwner {
        _TIMELOCK_ = block.timestamp + _TIMELOCK_DURATION_;
        _PENDING_ADD_DODO_PROXY_ = newDodoProxy;
    }

    function lockAddProxy() public onlyOwner {
       _PENDING_ADD_DODO_PROXY_ = address(0);
       _TIMELOCK_ = 0;
    }


    function addDODOProxy() external onlyOwner notLocked() {
        _IS_ALLOWED_PROXY_[_PENDING_ADD_DODO_PROXY_] = true;
        lockAddProxy();
        emit AddDODOProxy(_PENDING_ADD_DODO_PROXY_);
    }

    function removeDODOProxy (address oldDodoProxy) external onlyOwner {
        _IS_ALLOWED_PROXY_[oldDodoProxy] = false;
        emit RemoveDODOProxy(oldDodoProxy);
    }


    function claimERC721(
        address nftContract,
        address who,
        address dest,
        uint256 tokenId
    ) external {
        require(_IS_ALLOWED_PROXY_[msg.sender], "DODONFTApprove:Access restricted");
        IERC721(nftContract).safeTransferFrom(who, dest, tokenId);
    }

    function claimERC1155(
        address nftContract,
        address who,
        address dest,
        uint256 tokenId,
        uint256 amount
    ) external {
        require(_IS_ALLOWED_PROXY_[msg.sender], "DODONFTApprove:Access restricted");
        IERC1155(nftContract).safeTransferFrom(who, dest, tokenId, amount, "");
    } 

    function claimERC1155Batch(
        address nftContract,
        address who,
        address dest,
        uint256[] memory tokenIds,
        uint256[] memory amounts
    ) external {
        require(_IS_ALLOWED_PROXY_[msg.sender], "DODONFTApprove:Access restricted");
        IERC1155(nftContract).safeBatchTransferFrom(who, dest, tokenIds, amounts, "");
    } 

    function isAllowedProxy(address _proxy) external view returns (bool) {
        return _IS_ALLOWED_PROXY_[_proxy];
    }
}


Vulnerability type: CWE-284
HIGH severity: _rewardsToken can be arbitrary contract. Malicious user can attack target contract by passing a malicious _rewardsToken address.

Vulnerable code:
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.10;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";

interface Elipsis {
    function addReward(address _rewardsToken, address _rewardsDistributor, uint256 _rewardsDuration) external;
    function setRewardsDistributor(address _rewardsToken, address _rewardsDistributor) external;
    function setDepositContract(address _account, bool _isDepositContract) external;
    function notifyRewardAmount(address _rewardsToken, uint256 reward) external;
    function setRewardsDuration(address _rewardsToken, uint256 _rewardsDuration) external;
}

contract ElipsisMediator is Initializable{

    using SafeERC20Upgradeable for IERC20Upgradeable;

    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external auth { require(live == 1, "Mediator/not-live"); wards[usr] = 1; }
    function deny(address usr) external auth { require(live == 1, "Mediator/not-live"); wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Mediator/not-authorized");
        _;
    }

    // --- Operators ---
    mapping (address => uint) public operators;
    function relyOperator(address usr) external auth { require(live == 1, "Mediator/not-live"); operators[usr] = 1; }
    function denyOperator(address usr) external auth { require(live == 1, "Mediator/not-live"); operators[usr] = 0; }
    modifier authOrOperator {
        require(wards[msg.sender] == 1 || operators[msg.sender] == 1, "Mediator/not-operator");
        _;
    }

    // --- Vars ---
    Elipsis public target;
    uint256 public live;  // Active Flag

    // --- Init ---
    function initialize(address targetContract) public initializer {
        wards[msg.sender] = 1;
        target = Elipsis(targetContract);
        live = 1;
    }

    // --- Admin ---
    function changeTargetContract(address targetContract) external auth {
        require(live == 1, "mediator/not-live");
        target = Elipsis(targetContract);
    }

    // --- Mediator Functions ---
    function notifyRewardAmount(address _rewardsToken, uint256 reward) external authOrOperator {
        require(live == 1, "mediator/not-live");
        IERC20Upgradeable(_rewardsToken).safeTransferFrom(msg.sender, address(this), reward);
        IERC20Upgradeable(_rewardsToken).approve(address(target), reward);
        target.notifyRewardAmount(_rewardsToken, reward);
    }
    function setRewardsDuration(address _rewardsToken, uint256 _rewardsDuration) external authOrOperator {
        require(live == 1, "mediator/not-live");
        target.setRewardsDuration(_rewardsToken, _rewardsDuration);
    }
}

Vulnerability type: CWE-284
MEDIUM severity: Missing check BnbOracle status. Need to check roundID/startedAt/timeStamp/answeredInRound to get a correct price.

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

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract BnbOracle is Initializable {

    AggregatorV3Interface internal priceFeed;

    function initialize(address aggregatorAddress) external initializer {
        priceFeed = AggregatorV3Interface(aggregatorAddress);
    }

    /**
     * Returns the latest price
     */
    function peek() public view returns (bytes32, bool) {
        (
            /*uint80 roundID*/,
            int price,
            /*uint startedAt*/,
            /*uint timeStamp*/,
            /*uint80 answeredInRound*/
        ) = priceFeed.latestRoundData();
        if (price < 0) {
            return (0, false);
        }
        return (bytes32(uint(price) * (10**10)), true);
    }
}

Vulnerability type: CWE-703|CWE-754
HIGH severity: HelioOracle owner is never initialized. _owner is never initialized, changePriceToken call will fail in any condition.

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

pragma solidity ^0.8.10;

import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

import "../interfaces/PipLike.sol";

contract HelioOracle is PipLike, OwnableUpgradeable  {

    event PriceChanged(uint256 newPrice);

    address private _owner;
    uint256 private price;

    // --- Init ---
    function initialize(uint256 initialPrice) public initializer {
        __Ownable_init();

        price = initialPrice;
    }

    /**
     * Returns the latest price
     */
    function peek() public view returns (bytes32, bool) {
        return (bytes32(price), true);
    }

    function changePriceToken(uint256 price_) external {
        require(msg.sender == _owner, "HelioOracle/forbidden");
        price = price_;
        emit PriceChanged(price);
    }
}

Vulnerability type: CWE-664|CWE-665|CWE-909