lohoz/Smart-Contract-MultiTask-Dataset huggingface dataset:
// Solidity 0.6.12
/// @notice Checks if Boost/Repay could be triggered for the CDP
/// @dev Called by MCDMonitor to enforce the min/max check
function canCall(Method _method, uint _cdpId, uint _nextPrice) public view returns(bool, uint) {
        bool subscribed;
        CdpHolder memory holder;
        (subscribed, holder) = subscriptionsContract.getCdpHolder(_cdpId);

        // check if cdp is subscribed
        if (!subscribed) return (false, 0);

        // check if using next price is allowed
        if (_nextPrice > 0 && !holder.nextPriceEnabled) return (false, 0);

        // check if boost and boost allowed
        if (_method == Method.Boost && !holder.boostEnabled) return (false, 0);

        // check if owner is still owner
        if (getOwner(_cdpId) != holder.owner) return (false, 0);

        uint currRatio = getRatio(_cdpId, _nextPrice);

        if (_method == Method.Repay) {
            return (currRatio < holder.minRatio, currRatio);
        } else if (_method == Method.Boost) {
            return (currRatio > holder.maxRatio, currRatio);
        }
    }
// Solidity 0.6.12
/// @dev After the Boost/Repay check if the ratio doesn't trigger another call
function ratioGoodAfter(Method _method, uint _cdpId, uint _nextPrice) public view returns(bool, uint) {
        CdpHolder memory holder;

        (, holder) = subscriptionsContract.getCdpHolder(_cdpId);

        uint currRatio = getRatio(_cdpId, _nextPrice);

        if (_method == Method.Repay) {
            return (currRatio < holder.maxRatio, currRatio);
        } else if (_method == Method.Boost) {
            return (currRatio > holder.minRatio, currRatio);
        }
    }
// Solidity 0.6.12
/// @notice Helper method to payback the cream debt
/// @dev If amount is bigger it will repay the whole debt and send the extra to the _user
/// @param _amount Amount of tokens we want to repay
/// @param _cBorrowToken Ctoken address we are repaying
/// @param _borrowToken Token address we are repaying
/// @param _user Owner of the cream position we are paying back
function paybackDebt(uint _amount, address _cBorrowToken, address _borrowToken, address payable _user) internal {
        uint wholeDebt = CTokenInterface(_cBorrowToken).borrowBalanceCurrent(address(this));

        if (_amount > wholeDebt) {
            if (_borrowToken == ETH_ADDRESS) {
                _user.transfer((_amount - wholeDebt));
            } else {
                ERC20(_borrowToken).safeTransfer(_user, (_amount - wholeDebt));
            }

            _amount = wholeDebt;
        }

        approveCToken(_borrowToken, _cBorrowToken);

        if (_borrowToken == ETH_ADDRESS) {
            CEtherInterface(_cBorrowToken).repayBorrow{value: _amount}();
        } else {
            require(CTokenInterface(_cBorrowToken).repayBorrow(_amount) == 0);
        }
    }
// Solidity 0.6.12
/// @notice Calculates the fee amount
/// @param _amount Amount that is converted
/// @param _user Actuall user addr not DSProxy
/// @param _gasCost Ether amount of gas we are spending for tx
/// @param _cTokenAddr CToken addr. of token we are getting for the fee
/// @return feeAmount The amount we took for the fee
function getFee(uint _amount, address _user, uint _gasCost, address _cTokenAddr) internal returns (uint feeAmount) {
        uint fee = MANUAL_SERVICE_FEE;

        if (BotRegistry(BOT_REGISTRY_ADDRESS).botList(tx.origin)) {
            fee = AUTOMATIC_SERVICE_FEE;
        }

        address tokenAddr = getUnderlyingAddr(_cTokenAddr);

        if (Discount(DISCOUNT_ADDR).isCustomFeeSet(_user)) {
            fee = Discount(DISCOUNT_ADDR).getCustomServiceFee(_user);
        }

        feeAmount = (fee == 0) ? 0 : (_amount / fee);

        if (_gasCost != 0) {
            address oracle = ComptrollerInterface(COMPTROLLER).oracle();

            uint ethTokenPrice = CompoundOracleInterface(oracle).getUnderlyingPrice(_cTokenAddr);

            _gasCost = wdiv(_gasCost, ethTokenPrice);

            feeAmount = add(feeAmount, _gasCost);
        }

        // fee can't go over 20% of the whole amount
        if (feeAmount > (_amount / 5)) {
            feeAmount = _amount / 5;
        }

        if (tokenAddr == ETH_ADDRESS) {
            WALLET_ADDR.transfer(feeAmount);
        } else {
            ERC20(tokenAddr).safeTransfer(WALLET_ADDR, feeAmount);
        }
    }
// Solidity 0.6.12
/// @notice Calculates the gas cost of transaction and send it to wallet
/// @param _amount Amount that is converted
/// @param _gasCost Ether amount of gas we are spending for tx
/// @param _cTokenAddr CToken addr. of token we are getting for the fee
/// @return feeAmount The amount we took for the fee
function getGasCost(uint _amount, uint _gasCost, address _cTokenAddr) internal returns (uint feeAmount) {
        address tokenAddr = getUnderlyingAddr(_cTokenAddr);

        if (_gasCost != 0) {
            address oracle = ComptrollerInterface(COMPTROLLER).oracle();

            uint ethTokenPrice = CompoundOracleInterface(oracle).getUnderlyingPrice(_cTokenAddr);

            feeAmount = wdiv(_gasCost, ethTokenPrice);
        }

        // fee can't go over 20% of the whole amount
        if (feeAmount > (_amount / 5)) {
            feeAmount = _amount / 5;
        }

        if (tokenAddr == ETH_ADDRESS) {
            WALLET_ADDR.transfer(feeAmount);
        } else {
            ERC20(tokenAddr).safeTransfer(WALLET_ADDR, feeAmount);
        }
    }
// Solidity 0.6.12
/// @notice Returns the maximum amount of collateral available to withdraw
/// @dev Due to rounding errors the result is - 1% wei from the exact amount
/// @param _cCollAddress Collateral we are getting the max value of
/// @param _account Users account
/// @return Returns the max. collateral amount in that token
function getMaxCollateral(address _cCollAddress, address _account) public returns (uint) {
        (, uint liquidityInEth, ) = ComptrollerInterface(COMPTROLLER).getAccountLiquidity(_account);
        uint usersBalance = CTokenInterface(_cCollAddress).balanceOfUnderlying(_account);
        address oracle = ComptrollerInterface(COMPTROLLER).oracle();

        if (liquidityInEth == 0) return usersBalance;

        CTokenInterface(_cCollAddress).accrueInterest();

         if (_cCollAddress == CETH_ADDRESS) {
             if (liquidityInEth > usersBalance) return usersBalance;

             return sub(liquidityInEth, (liquidityInEth / 100));
         }

        uint ethPrice = CompoundOracleInterface(oracle).getUnderlyingPrice(_cCollAddress);
        uint liquidityInToken = wdiv(liquidityInEth, ethPrice);

        if (liquidityInToken > usersBalance) return usersBalance;

        return sub(liquidityInToken, (liquidityInToken / 100)); // cut off 1% due to rounding issues
    }
// Solidity 0.5.11
/**
 * Close the current stage.
 */
function _closeStage() private {
            _stage = _stage.add(1);
            emit StageClosed(_stage);

            // Close current season
            uint16 __seasonNumber = _seasonNumber(_stage);
            if (_season < __seasonNumber) {
                _season = __seasonNumber;
                emit SeasonClosed(_season);
            }

            _vokenUsdPrice = _calcVokenUsdPrice(_stage);
            _shareholdersRatio = _calcShareholdersRatio(_stage);
        }
// Solidity 0.5.11
/**
 * @dev Returns the {limitIndex} and {weiMax}.
 */
function _limit(uint256 weiAmount) private view returns (uint256 __wei) {
            uint256 __purchased = _weiSeasonAccountPurchased[_season][msg.sender];
            for(uint16 i = 0; i < LIMIT_WEIS.length; i++) {
                if (__purchased >= LIMIT_WEIS[i]) {
                    return 0;
                }

                if (__purchased < LIMIT_WEIS[i]) {
                    __wei = LIMIT_WEIS[i].sub(__purchased);
                    if (weiAmount >= __wei && _seasonLimitAccounts[_season][i].length < LIMIT_COUNTER[i]) {
                        return __wei;
                    }
                }
            }

            if (__purchased < LIMIT_WEI_MIN) {
                return LIMIT_WEI_MIN.sub(__purchased);
            }
        }
// Solidity 0.5.11
/**
 * @dev Updates the season limit accounts, or wei min accounts.
 */
function _updateSeasonLimits() private {
            uint256 __purchased = _weiSeasonAccountPurchased[_season][msg.sender];
            if (__purchased > LIMIT_WEI_MIN) {
                for(uint16 i = 0; i < LIMIT_WEIS.length; i++) {
                    if (__purchased >= LIMIT_WEIS[i]) {
                        _seasonLimitAccounts[_season][i].push(msg.sender);
                        return;
                    }
                }
            }

            else if (__purchased == LIMIT_WEI_MIN) {
                _seasonLimitWeiMinAccounts[_season].push(msg.sender);
                return;
            }
        }
// Solidity 0.5.11
/**
 * @dev Returns the accounts of wei limit, by `seasonNumber` and `limitIndex`.
 */
function seasonLimitAccounts(uint16 seasonNumber, uint16 limitIndex) public view returns (uint256 weis, address[] memory accounts) {
            if (limitIndex < LIMIT_WEIS.length) {
                weis = LIMIT_WEIS[limitIndex];
                accounts = _seasonLimitAccounts[seasonNumber][limitIndex];
            }

            else {
                weis = LIMIT_WEI_MIN;
                accounts = _seasonLimitWeiMinAccounts[seasonNumber];
            }
        }
// Solidity 0.5.11
/**
 * @dev Cache.
 */
function _cache() private {
            if (!_seasonHasAccount[_season][msg.sender]) {
                _seasonAccounts[_season].push(msg.sender);
                _seasonHasAccount[_season][msg.sender] = true;
            }

            _cacheWhitelisted = _VOKEN.whitelisted(msg.sender);
            if (_cacheWhitelisted) {
                address __account = msg.sender;
                for(uint16 i = 0; i < REWARDS_PCT.length; i++) {
                    address __referee = _VOKEN.whitelistReferee(__account);

                    if (__referee != address(0) && __referee != __account && _VOKEN.whitelistReferralsCount(__referee) > i) {
                        if (!_seasonHasReferral[_season][__referee]) {
                            _seasonReferrals[_season].push(__referee);
                            _seasonHasReferral[_season][__referee] = true;
                        }

                        if (!_seasonAccountHasReferral[_season][__referee][__account]) {
                            _seasonAccountReferrals[_season][__referee].push(__account);
                            _seasonAccountHasReferral[_season][__referee][__account] = true;
                        }

                        _cacheReferees.push(address(uint160(__referee)));
                        _cacheRewards.push(REWARDS_PCT[i]);
                    }
                    else {
                        _cachePended = _cachePended.add(REWARDS_PCT[i]);
                    }

                    __account = __referee;
                }
            }
        }
// Solidity 0.5.11
/**
 * @dev USD => Voken
 */
function _tx(uint256 __usd) private returns (uint256 __voken, uint256 __usdRemain) {
            uint256 __stageUsdCap = _stageUsdCap(_stage);
            uint256 __usdUsed;

            // in stage
            if (_stageUsdSold[_stage].add(__usd) <= __stageUsdCap) {
                __usdUsed = __usd;

                (__voken, ) = _calcExchange(__usdUsed);
                _mintVokenIssued(__voken);

                // close stage, if stage dollor cap reached
                if (__stageUsdCap == _stageUsdSold[_stage]) {
                    _closeStage();
                }
            }

            // close stage
            else {
                __usdUsed = __stageUsdCap.sub(_stageUsdSold[_stage]);

                (__voken, ) = _calcExchange(__usdUsed);
                _mintVokenIssued(__voken);

                _closeStage();

                __usdRemain = __usd.sub(__usdUsed);
            }
        }
// Solidity 0.5.11
/**
 * @dev USD => voken & wei, and make records.
 */
function _calcExchange(uint256 __usd) private returns (uint256 __voken, uint256 __wei) {
            __wei = _usd2wei(__usd);
            __voken = _usd2voken(__usd);

            uint256 __weiShareholders = _usd2wei(_2shareholders(__usd));

            // Stage: usd
            _stageUsdSold[_stage] = _stageUsdSold[_stage].add(__usd);

            // Season: wei
            _seasonWeiSold[_season] = _seasonWeiSold[_season].add(__wei);

            // Season: wei pended
            if (_cachePended > 0) {
                _seasonWeiPended[_season] = _seasonWeiPended[_season].add(__wei.mul(_cachePended).div(100));
            }

            // Season shareholders: wei
            _seasonWeiShareholders[_season] = _seasonWeiShareholders[_season].add(__weiShareholders);

            // Cache
            _cacheWeiShareholders = _cacheWeiShareholders.add(__weiShareholders);

            // Season => account: wei
            _weiSeasonAccountPurchased[_season][msg.sender] = _weiSeasonAccountPurchased[_season][msg.sender].add(__wei);

            // season referral account
            if (_cacheWhitelisted) {
                for (uint16 i = 0; i < _cacheRewards.length; i++) {
                    address __referee = _cacheReferees[i];
                    uint256 __weiReward = __wei.mul(_cacheRewards[i]).div(100);

                    // 
                    if (i == 0) {
                        _accountVokenReferral[__referee] = _accountVokenReferral[__referee].add(__voken);
                        _vokenSeasonAccountReferral[_season][__referee] = _vokenSeasonAccountReferral[_season][__referee].add(__voken);
                    }

                    // season
                    _seasonWeiRewarded[_season] = _seasonWeiRewarded[_season].add(__weiReward);

                    // season => account
                    _accountVokenReferrals[__referee] = _accountVokenReferrals[__referee].add(__voken);
                    _vokenSeasonAccountReferrals[_season][__referee] = _vokenSeasonAccountReferrals[_season][__referee].add(__voken);
                    _weiSeasonAccountReferrals[_season][__referee] = _weiSeasonAccountReferrals[_season][__referee].add(__wei);
                    _weiSeasonAccountRewarded[_season][__referee] = _weiSeasonAccountRewarded[_season][__referee].add(__weiReward);
                }
            }
        }
// Solidity 0.5.11
/**
 * @dev Mint Voken issued.
 */
function _mintVokenIssued(uint256 amount) private {
            // Global
            _vokenIssued = _vokenIssued.add(amount);
            _vokenIssuedTxs = _vokenIssuedTxs.add(1);

            // Account
            _accountVokenIssued[msg.sender] = _accountVokenIssued[msg.sender].add(amount);

            // Stage
            _stageVokenIssued[_stage] = _stageVokenIssued[_stage].add(amount);

            // Season
            _seasonVokenIssued[_season] = _seasonVokenIssued[_season].add(amount);
            _vokenSeasonAccountIssued[_season][msg.sender] = _vokenSeasonAccountIssued[_season][msg.sender].add(amount);

            // Mint
            assert(_VOKEN.mint(msg.sender, amount));
        }
// Solidity 0.5.11
/**
 * @dev Mint Voken bonus.
 */
function _mintVokenBonus(uint256 amount) private {
            // Global
            _vokenBonus = _vokenBonus.add(amount);
            _vokenBonusTxs = _vokenBonusTxs.add(1);

            // Account
            _accountVokenBonus[msg.sender] = _accountVokenBonus[msg.sender].add(amount);

            // Stage
            _stageVokenBonus[_stage] = _stageVokenBonus[_stage].add(amount);

            // Season
            _seasonVokenBonus[_season] = _seasonVokenBonus[_season].add(amount);
            _vokenSeasonAccountBonus[_season][msg.sender] = _vokenSeasonAccountBonus[_season][msg.sender].add(amount);

            // Mint with allocation
            Allocations.Allocation memory __allocation;
            __allocation.amount = amount;
            __allocation.timestamp = now;
            _allocations[msg.sender].push(__allocation);
            assert(_VOKEN.mintWithAllocation(msg.sender, amount, address(this)));
        }
// Solidity 0.4.25
/**
 * @dev Complete an order combination and issue the loan to the borrower.
 * @param _taker address of investor.
 * @param _toTime order repayment due date.
 * @param _repaymentSum total amount of money that the borrower ultimately needs to return.
 */
function takerOrder(address _taker, uint32 _toTime, uint256 _repaymentSum) public onlyOwnerOrPartner {
    require(_taker != address(0) && _toTime > 0 && now <= _toTime && _repaymentSum > 0 && status == StatusChoices.NO_LOAN);
    taker = _taker;
    toTime = _toTime;
    repaymentSum = _repaymentSum;

    // Transfer the token provided by the investor to the borrower's address
    if (loanTokenName.stringCompare(TOKEN_ETH)) {
      require(ethAmount[_taker] > 0 && address(this).balance > 0);
      outLoanSum = address(this).balance;
      maker.transfer(outLoanSum);
    } else {
      require(token20 != address(0) && ERC20(token20).balanceOf(address(this)) > 0);
      outLoanSum = ERC20(token20).balanceOf(address(this));
      require(safeErc20Transfer(maker, outLoanSum));
    }

    // Update contract business execution status.
    status = StatusChoices.REPAYMENT_WAITING;

    emit TakerOrder(taker, outLoanSum);
  }
// Solidity 0.4.25
/**
 * @dev Only the full repayment will execute the contract agreement.
 */
function executeOrder() public onlyOwnerOrPartner {
    require(now <= toTime && status == StatusChoices.REPAYMENT_WAITING);
    // The borrower pays off the loan and performs two-way operation.
    if (loanTokenName.stringCompare(TOKEN_ETH)) {
      require(ethAmount[maker] >= repaymentSum && address(this).balance >= repaymentSum);
      lastRepaymentSum = address(this).balance;
      taker.transfer(repaymentSum);
    } else {
      require(ERC20(token20).balanceOf(address(this)) >= repaymentSum);
      lastRepaymentSum = ERC20(token20).balanceOf(address(this));
      require(safeErc20Transfer(taker, repaymentSum));
    }

    PledgeContract(owner)._conclude();
    status = StatusChoices.REPAYMENT_ALL;
    emit ExecuteOrder(maker, lastRepaymentSum);
  }
// Solidity 0.4.25
/**
 * @dev Close position or due repayment operation.
 */
function forceCloseOrder() public onlyOwnerOrPartner {
    require(status == StatusChoices.REPAYMENT_WAITING);
    uint256 transferSum = 0;

    if (now <= toTime) {
      status = StatusChoices.CLOSE_POSITION;
    } else {
      status = StatusChoices.OVERDUE_STOP;
    }

    if(loanTokenName.stringCompare(TOKEN_ETH)){
        if(ethAmount[maker] > 0 && address(this).balance > 0){
            transferSum = address(this).balance;
            maker.transfer(transferSum);
        }
    }else{
        if(ERC20(token20).balanceOf(address(this)) > 0){
            transferSum = ERC20(token20).balanceOf(address(this));
            require(safeErc20Transfer(maker, transferSum));
        }
    }

    // Return pledge token.
    PledgeContract(owner)._forceConclude(taker);
    emit ForceCloseOrder(toTime, transferSum);
  }
// Solidity 0.4.25
/**
 * @dev Withdrawal of the token invested by the taker.
 * @param _taker address of investor.
 * @param _refundSum refundSum number of tokens withdrawn.
 */
function withdrawToken(address _taker, uint256 _refundSum) public onlyOwnerOrPartner {
    require(status == StatusChoices.NO_LOAN);
    require(_taker != address(0) && _refundSum > 0);
    if (loanTokenName.stringCompare(TOKEN_ETH)) {
      require(address(this).balance >= _refundSum && ethAmount[_taker] >= _refundSum);
      _taker.transfer(_refundSum);
      ethAmount[_taker] = ethAmount[_taker].sub(_refundSum);
    } else {
      require(ERC20(token20).balanceOf(address(this)) >= _refundSum);
      require(safeErc20Transfer(_taker, _refundSum));
    }
    emit WithdrawToken(_taker, _refundSum);
  }
// Solidity 0.4.25
/**
 * @dev Get current contract order status.
 */
function getPledgeStatus() public view returns(string pledgeStatus) {
    if (status == StatusChoices.NO_LOAN) {
      pledgeStatus = "NO_LOAN";
    } else if (status == StatusChoices.REPAYMENT_WAITING) {
      pledgeStatus = "REPAYMENT_WAITING";
    } else if (status == StatusChoices.REPAYMENT_ALL) {
      pledgeStatus = "REPAYMENT_ALL";
    } else if (status == StatusChoices.CLOSE_POSITION) {
      pledgeStatus = "CLOSE_POSITION";
    } else {
      pledgeStatus = "OVERDUE_STOP";
    }
  }
// Solidity 0.4.25
/**
 * @dev Create a pledge subcontract
 * @param _pledgeId index number of the pledge contract.
 */
function createPledgeContract(uint256 _pledgeId, address _escrowPartner) public onlyPartner returns(bool) {
    require(_pledgeId > 0 && !isPledgeId[_pledgeId] && _escrowPartner!=address(0));

    // Give the pledge contract the right to update statistics.
    PledgeContract pledgeAddress = new PledgeContract(_pledgeId, address(this),partner);
    pledgeAddress.transferOwnership(_escrowPartner);
    addOperater(address(pledgeAddress));

    // update pledge contract info
    isPledgeId[_pledgeId] = true;
    pledgeEscrowById[_pledgeId] = EscrowPledge(pledgeAddress, INIT_TOKEN_NAME);

    emit CreatePledgeContract(_pledgeId, address(pledgeAddress));
    return true;
  }
// Solidity 0.4.25
// -----------------------------------------
// external interface
// -----------------------------------------
function() external payable {
    require(status != StatusChoices.PLEDGE_REFUND);
    // Identify the borrower.
    if (maker != address(0)) {
      require(address(msg.sender) == maker);
    }
    // Record basic information about the borrower's pledge ETH
    verifyEthAccount[msg.sender] = verifyEthAccount[msg.sender].add(msg.value);
  }
// Solidity 0.4.25
/**
 * @dev Add the pledge information and transfer the pledged token into the corresponding currency pool.
 * @param _pledgeTokenName maker pledge token name.
 * @param _maker borrower address.
 * @param _pledgeSum pledge amount.
 * @param _loanTokenName pledge token type.
 */
function addRecord(string _pledgeTokenName, address _maker, uint256 _pledgeSum, string _loanTokenName) public onlyOwner {
    require(_maker != address(0) && _pledgeSum > 0 && status != StatusChoices.PLEDGE_REFUND);
    // Add the pledge information for the first time.
    if (status == StatusChoices.NO_PLEDGE_INFO) {
      // public data init.
      maker = _maker;
      pledgeTokenName = _pledgeTokenName;
      tokenPoolAddress = checkedTokenPool(pledgeTokenName);
      PledgeFactory(factory).updatePledgeType(pledgeId, pledgeTokenName);
      // Assign rights to the operation of the contract pool
      PledgeFactory(factory).tokenPoolOperater(tokenPoolAddress, address(this));
      // Create order management contracts.
      createOrderContract(_loanTokenName);
    }
    // Record information of each pledge.
    pledgeAccountSum = pledgeAccountSum.add(_pledgeSum);
    PledgePoolBase(tokenPoolAddress).addRecord(maker, pledgeAccountSum, pledgeId, pledgeTokenName);
    // Transfer the pledge token to the appropriate token pool.
    if (pledgeTokenName.stringCompare(TOKEN_ETH)) {
      require(verifyEthAccount[maker] >= _pledgeSum);
      tokenPoolAddress.transfer(_pledgeSum);
    } else {
      token20 = checkedToken(pledgeTokenName);
      require(ERC20(token20).balanceOf(address(this)) >= _pledgeSum);
      require(safeErc20Transfer(token20,tokenPoolAddress, _pledgeSum));
    }
  }