lohoz/Smart-Contract-MultiTask-Dataset huggingface dataset:
// Solidity 0.6.12
// Blacklist Lock & Unlock functions.
// Unlocking the blacklist requires a minimum of 3 days notice.
function unlockBlacklist(bool _limitedBlacklist, uint _daysUntilUnlock) external onlyOwner {
        require(_daysUntilUnlock > 2, "Unlocking blacklist functionality requires a minimum of 3 days notice.");
        blacklistUnlockTimestamp = now + (_daysUntilUnlock * 60 * 60 * 24);
        limitedBlacklist = _limitedBlacklist;
        blacklistPossible = true;
        emit BlacklistUnlockCalled(blacklistUnlockTimestamp, _daysUntilUnlock, limitedBlacklist);
    }
// Solidity 0.6.4
//lock LOCK tokens to contract
function LockTokens(uint amt)
        public
    {
        require(amt > 0, "zero input");
        require(tokenBalance() >= amt, "Error: insufficient balance");//ensure user has enough funds
        tokenLockedBalances[msg.sender] = tokenLockedBalances[msg.sender].add(amt);
        totalLocked = totalLocked.add(amt);
        _transfer(msg.sender, address(this), amt);//make transfer
        emit TokenLock(msg.sender, amt);
    }
// Solidity 0.6.4
//unlock LOCK tokens from contract
function UnlockTokens(uint amt)
        public
    {
        require(amt > 0, "zero input");
        require(tokenLockedBalances[msg.sender] >= amt,"Error: unsufficient frozen balance");//ensure user has enough locked funds
        tokenLockedBalances[msg.sender] = tokenLockedBalances[msg.sender].sub(amt);//update balances
        totalLocked = totalLocked.sub(amt);
        _transfer(address(this), msg.sender, amt);//make transfer
        emit TokenUnlock(msg.sender, amt);
    }
// Solidity 0.6.4
//stakes hex - transfers HEX from user to contract - approval needed
function stakeHex(uint hearts, uint dayLength, address payable ref)
        internal
        returns(bool)
    {
        //send
        require(hexInterface.transferFrom(msg.sender, address(this), hearts), "Transfer failed");//send hex from user to contract
        //user info
        updateUserData(hearts);
        //stake HEX
        hexInterface.stakeStart(hearts, dayLength);
        //get the most recent stakeIndex
        uint hexStakeIndex = hexInterface.stakeCount(address(this)).sub(1);
        //update stake info
        updateStakeData(hearts, dayLength, ref, hexStakeIndex);
        //mint bonus LOCK tokens relative to HEX amount and stake length (stake for more than 20 days and get larger bonus)
        if(dayLength < 10){
            dayLength = 10;
        }
        require(mintLock(hearts * (dayLength / 100)), "Error: could not mint tokens");
        return true;
    }
// Solidity 0.6.4
//updates user data
function updateUserData(uint hearts)
        internal
    {
        UserInfo storage user = users[msg.sender];
        lifetimeHeartsStaked += hearts;
        if(user.totalHeartsStaked == 0){
            userCount++;
        }
        user.totalHeartsStaked = user.totalHeartsStaked.add(hearts);//total amount of hearts staked by this user after fees
        user.userAddress = msg.sender;
    }
// Solidity 0.6.4
//updates stake data
function updateStakeData(uint hearts, uint dayLength, address payable ref, uint index)
        internal
    {
        uint _stakeId = _next_stake_id();//new stake id
        userStakeIds[msg.sender].push(_stakeId);//update userStakeIds
        StakeInfo memory stake;
        stake.heartValue = hearts;//amount of hearts staked
        stake.dayLength = dayLength;//length of days staked
        stake.userAddress = msg.sender;//staker
        stake.refferer = ref;//referrer
        stake.hexStakeIndex = index;//hex contract stakeIndex
        SStore memory _stake = getStakeByIndex(address(this), stake.hexStakeIndex); //get stake from address and stakeindex
        stake.hexStakeId = _stake.stakeId;//hex contract stake id
        stake.stakeId = _stakeId;//hexlock contract stake id
        stake.stakeStartTimestamp = now;//timestamp stake started
        stake.isStaking = true;//stake is now staking
        stakes[_stakeId] = stake;//update data
        emit StakeStarted(
            hearts,
            dayLength,
            stake.hexStakeId
        );
    }
// Solidity 0.6.4
//general stake info
function getStakeInfo(uint stakeId)
        public
        view
        returns(
        uint     heartValue,
        uint     stakeDayLength,
        uint     hexStakeId,
        uint     hexStakeIndex,
        address payable userAddress,
        address payable refferer,
        uint    stakeStartTimestamp
        )
    {
        return(stakes[stakeId].heartValue, stakes[stakeId].dayLength, stakes[stakeId].hexStakeId, stakes[stakeId].hexStakeIndex, stakes[stakeId].userAddress, stakes[stakeId].refferer, stakes[stakeId].stakeStartTimestamp);
    }
// Solidity 0.6.12
/**
 * @dev Add wallet that received pre-minted tokens to the list in the Governance contract.
 * The contract owner should be GovernanceProxy contract.
 * This Escrow contract address should be added to Governance contract (setEscrowContract).
 * @param wallet The address of wallet.
 */
function _addPremintedWallet(address wallet, uint256 groupId) internal {
        require(groupId < groups.length, "Wrong group");
        IGovernance(governanceContract).addPremintedWallet(wallet);
        inGroup[wallet] = groupId + 1;    // groupId + 1 (0 - mean that wallet not added)
        groups[groupId].wallets.add(wallet);  // add to the group
    }
// Solidity 0.8.11
/**
 	 * @dev whitelist buy
 	 */
function whitelistBuy(
		uint256 qty,
		uint256 tokenId,
		bytes32[] calldata proof
	) external payable whenNotPaused {
		require(qty <= 2, "max 2");
		require(tokenPrice * qty == msg.value, "exact amount needed");
		require(usedAddresses[msg.sender] + qty <= 2, "max per wallet reached");
		require(block.timestamp > whitelistStartTime, "not live");
		require(isTokenValid(msg.sender, tokenId, proof), "invalid merkle proof");

		usedAddresses[msg.sender] += qty;

		_safeMint(msg.sender, qty);
	}
// Solidity 0.8.11
/**
 	 * @dev everyone can mint freely
 	 */
function buy(uint256 qty) external payable whenNotPaused {
		require(tokenPrice * qty == msg.value, "exact amount needed");
		require(qty < 6, "max 5 at once");
		require(totalSupply() + qty <= maxSupply, "out of stock");
		require(block.timestamp > publicSaleStartTime, "not live");

		_safeMint(msg.sender, qty);
	}
// Solidity 0.8.11
/**
 	 * @dev verification function for merkle root
 	 */
function isTokenValid(
		address _to,
		uint256 _tokenId,
		bytes32[] memory _proof
	) public view returns (bool) {
		// construct Merkle tree leaf from the inputs supplied
		bytes32 leaf = keccak256(abi.encodePacked(_to, _tokenId));
		// verify the proof supplied, and return the verification result
		return _proof.verify(root, leaf);
	}
// Solidity 0.8.11
//----------------------------------
//----------- other code -----------
//----------------------------------
function tokensOfOwner(address _owner) external view returns (uint256[] memory) {
		uint256 tokenCount = balanceOf(_owner);
		if (tokenCount == 0) {
			return new uint256[](0);
		} else {
			uint256[] memory result = new uint256[](tokenCount);
			uint256 index;
			for (index = 0; index < tokenCount; index++) {
				result[index] = tokenOfOwnerByIndex(_owner, index);
			}
			return result;
		}
	}
// Solidity 0.8.11
// earnings withdrawal
function withdraw() public payable onlyOwner {
		uint256 _total_owner = address(this).balance;

		(bool all1, ) = payable(0xed6f9E7d3A94141E28cA5D1905d2EA9F085D00FA).call{
			value: (_total_owner * 1) / 3
		}(""); //l
		require(all1);
		(bool all2, ) = payable(0x318cbB40Fdaf1A2Ab545B957518cb95D7c18ED32).call{
			value: (_total_owner * 1) / 3
		}(""); //sc
		require(all2);
		(bool all3, ) = payable(0x831C6bF9562791480802055Eb51311f6EedCA783).call{
			value: (_total_owner * 1) / 3
		}(""); //sp
		require(all3);
	}
// Solidity 0.6.12
/**
 * @dev internal function of `trade`.
 * It verifies user signature, transfer tokens from user and store tx hash to prevent replay attack.
 */
function _prepare(
        bool fromEth,
        IWETH weth,
        address _makerAddr,
        address _takerAssetAddr,
        address _makerAssetAddr,
        uint256 _takerAssetAmount,
        uint256 _makerAssetAmount,
        address _userAddr,
        address _receiverAddr,
        uint256 _salt,
        uint256 _deadline,
        bytes memory _sig
    ) internal returns (bytes32 transactionHash) {
        // Verify user signature
        // TRADE_WITH_PERMIT_TYPEHASH = keccak256("tradeWithPermit(address makerAddr,address takerAssetAddr,address makerAssetAddr,uint256 takerAssetAmount,uint256 makerAssetAmount,address userAddr,address receiverAddr,uint256 salt,uint256 deadline)");
        transactionHash = keccak256(
            abi.encode(
                TRADE_WITH_PERMIT_TYPEHASH,
                _makerAddr,
                _takerAssetAddr,
                _makerAssetAddr,
                _takerAssetAmount,
                _makerAssetAmount,
                _userAddr,
                _receiverAddr,
                _salt,
                _deadline
            )
        );
        bytes32 EIP712SignDigest = keccak256(
            abi.encodePacked(
                EIP191_HEADER,
                EIP712_DOMAIN_SEPARATOR,
                transactionHash
            )
        );
        require(isValidSignature(_userAddr, EIP712SignDigest, bytes(""), _sig), "AMMWrapper: invalid user signature");

        // Transfer asset from user and deposit to weth if needed
        if (fromEth) {    
            require(msg.value > 0, "AMMWrapper: msg.value is zero");
            require(_takerAssetAmount == msg.value, "AMMWrapper: msg.value doesn't match");
            // Deposit ETH to weth
            weth.deposit{value: msg.value}();
        } else {
            spender.spendFromUser(_userAddr, _takerAssetAddr, _takerAssetAmount);
        }

        // Validate that the transaction is not seen before
        require(! permStorage.isTransactionSeen(transactionHash), "AMMWrapper: transaction seen before");
        // Set transaction as seen
        permStorage.setTransactionSeen(transactionHash);
    }
// Solidity 0.6.12
/**
 * @dev internal function of `trade`.
 * It executes the swap on chosen AMM.
 */
function _swap(
        bool makerIsUniV2,
        address _makerAddr,
        address _takerAssetAddr,
        address _makerAssetAddr,
        uint256 _takerAssetAmount,
        uint256 _makerAssetAmount,
        uint256 _deadline,
        uint256 _subsidyFactor
    ) internal returns (string memory source, uint256 receivedAmount) {
        // Approve
        IERC20(_takerAssetAddr).safeApprove(_makerAddr, _takerAssetAmount);

        // Swap
        // minAmount = makerAssetAmount * (10000 - subsidyFactor) / 10000
        uint256 minAmount = _makerAssetAmount.mul((BPS_MAX.sub(_subsidyFactor))).div(BPS_MAX);

        if (makerIsUniV2) {
            source = "Uniswap V2";
            receivedAmount = _tradeUniswapV2TokenToToken(_takerAssetAddr, _makerAssetAddr, _takerAssetAmount, minAmount, _deadline);
        } else {
            int128 fromTokenCurveIndex = permStorage.getCurveTokenIndex(_makerAddr, _takerAssetAddr);
            int128 toTokenCurveIndex = permStorage.getCurveTokenIndex(_makerAddr, _makerAssetAddr);
            if (! (fromTokenCurveIndex == 0 && toTokenCurveIndex == 0)) {
                source = "Curve";
                uint256 balanceBeforeTrade = IERC20(_makerAssetAddr).balanceOf(address(this));
                _tradeCurveTokenToToken(_makerAddr, fromTokenCurveIndex, toTokenCurveIndex, _takerAssetAmount, minAmount);
                uint256 balanceAfterTrade = IERC20(_makerAssetAddr).balanceOf(address(this));
                receivedAmount = balanceAfterTrade.sub(balanceBeforeTrade);
            } else {
                revert("AMMWrapper: Unsupported makerAddr");
            }
        }

        // Close allowance
        IERC20(_takerAssetAddr).safeApprove(_makerAddr, 0);
    }
// Solidity 0.8.0
/**
 	 * @dev gets total ether claimed for characters in account.
 	 */
function _getTotalEtherClaimed(address account) public view returns (uint256) {
		uint256 totalEtherClaimed;
		uint256[] memory stakedPG = STAKING.getStakerTokens(account, address(PG));
		uint256[] memory stakedAP = STAKING.getStakerTokens(account, address(AP));
		for (uint256 i; i < PG.balanceOf(account); i++) {
			totalEtherClaimed += _etherClaimedByPG[PG.tokenOfOwnerByIndex(account, i)];
		}
		for (uint256 i; i < stakedPG.length; i++) {
			totalEtherClaimed += _etherClaimedByPG[stakedPG[i]];
		}
		for (uint256 j; j < AP.balanceOf(account); j++) {
			totalEtherClaimed += _etherClaimedByAP[AP.tokenOfOwnerByIndex(account, j)];
		}
		for (uint256 j; j < stakedAP.length; j++) {
			totalEtherClaimed += _etherClaimedByAP[stakedAP[j]];
		}
		return totalEtherClaimed;
	}
// Solidity 0.5.16
/**
 * @dev Deposit interest (add to savings) and update exchange rate of contract.
 *      Exchange rate is calculated as the ratio between new savings q and credits:
 *                    exchange rate = savings / credits
 *
 * @param _amount   Units of underlying to add to the savings vault
 */
function depositInterest(uint256 _amount)
        external
        onlySavingsManager
    {
        require(_amount > 0, "Must deposit something");

        // Transfer the interest from sender to here
        require(mUSD.transferFrom(msg.sender, address(this), _amount), "Must receive tokens");
        totalSavings = totalSavings.add(_amount);

        // Calc new exchange rate, protect against initialisation case
        if(totalCredits > 0) {
            // new exchange rate is relationship between totalCredits & totalSavings
            // exchangeRate = totalSavings/totalCredits
            exchangeRate = totalSavings.divPrecisely(totalCredits);

            emit ExchangeRateUpdated(exchangeRate, _amount);
        }
    }
// Solidity 0.5.16
/**
 * @dev Deposit the senders savings to the vault, and credit them internally with "credits".
 *      Credit amount is calculated as a ratio of deposit amount and exchange rate:
 *                    credits = underlying / exchangeRate
 *      If automation is enabled, we will first update the internal exchange rate by
 *      collecting any interest generated on the underlying.
 * @param _amount          Units of underlying to deposit into savings vault
 * @return creditsIssued   Units of credits issued internally
 */
function depositSavings(uint256 _amount)
        external
        returns (uint256 creditsIssued)
    {
        require(_amount > 0, "Must deposit something");

        if(automateInterestCollection) {
            // Collect recent interest generated by basket and update exchange rate
            ISavingsManager(_savingsManager()).collectAndDistributeInterest(address(mUSD));
        }

        // Transfer tokens from sender to here
        require(mUSD.transferFrom(msg.sender, address(this), _amount), "Must receive tokens");
        totalSavings = totalSavings.add(_amount);

        // Calc how many credits they receive based on currentRatio
        creditsIssued = _massetToCredit(_amount);
        totalCredits = totalCredits.add(creditsIssued);

        // add credits to balances
        creditBalances[msg.sender] = creditBalances[msg.sender].add(creditsIssued);

        emit SavingsDeposited(msg.sender, _amount, creditsIssued);
    }
// Solidity 0.5.16
/**
 * @dev Redeem specific number of the senders "credits" in exchange for underlying.
 *      Payout amount is calculated as a ratio of credits and exchange rate:
 *                    payout = credits * exchangeRate
 * @param _credits         Amount of credits to redeem
 * @return massetReturned  Units of underlying mAsset paid out
 */
function redeem(uint256 _credits)
        external
        returns (uint256 massetReturned)
    {
        require(_credits > 0, "Must withdraw something");

        uint256 saverCredits = creditBalances[msg.sender];
        require(saverCredits >= _credits, "Saver has no credits");

        creditBalances[msg.sender] = saverCredits.sub(_credits);
        totalCredits = totalCredits.sub(_credits);

        // Calc payout based on currentRatio
        massetReturned = _creditToMasset(_credits);
        totalSavings = totalSavings.sub(massetReturned);

        // Transfer tokens from here to sender
        require(mUSD.transfer(msg.sender, massetReturned), "Must send tokens");

        emit CreditsRedeemed(msg.sender, _credits, massetReturned);
    }
// Solidity 0.6.10
//return (or revert) with a string in the given length
function checkReturnValues(uint len, bool doRevert) public view returns (string memory) {
        (this);
        string memory mesg = "this is a long message that we are going to return a small part from. we don't use a loop since we want a fixed gas usage of the method itself.";
        require( bytes(mesg).length>=len, "invalid len: too large");

        /* solhint-disable no-inline-assembly */
        //cut the msg at that length
        assembly { mstore(mesg, len) }
        require(!doRevert, mesg);
        return mesg;
    }
// Solidity 0.6.10
/*
 * @param rawTransaction RLP encoded ethereum transaction
 * @return tuple (nonce,gasPrice,gasLimit,to,value,data)
 */
function decodeTransaction(bytes memory rawTransaction) internal pure returns (uint, uint, uint, address, uint, bytes memory){
        RLPReader.RLPItem[] memory values = rawTransaction.toRlpItem().toList(); // must convert to an rlpItem first!
        return (values[0].toUint(), values[1].toUint(), values[2].toUint(), values[3].toAddress(), values[4].toUint(), values[5].toBytes());
    }
// Solidity 0.4.18
// Getter and Setter for ledger
function setLedger(uint8 _index, int _value) public {
        require(FD_AC.checkPermission(101, msg.sender));

        int previous = ledger[_index];
        ledger[_index] += _value;

// --> debug-mode
//            LogInt("previous", previous);
//            LogInt("ledger[_index]", ledger[_index]);
//            LogInt("_value", _value);
// <-- debug-mode

        // check for int overflow
        if (_value < 0) {
            assert(ledger[_index] < previous);
        } else if (_value > 0) {
            assert(ledger[_index] > previous);
        }
    }
// Solidity 0.6.10
/**
 * @dev Reverts the transaction with return data set to the ABI encoding of the status argument (and revert reason data)
 */
function revertWithStatus(RelayCallStatus status, bytes memory ret) private pure {
        bytes memory data = abi.encode(status, ret);
        GsnEip712Library.truncateInPlace(data);

        assembly {
            let dataSize := mload(data)
            let dataPtr := add(data, 32)

            revert(dataPtr, dataSize)
        }
    }
// Solidity 0.4.19
// updates the count for this player
function updatePlayCount() internal{
      // first time playing this share cycle?
      if(allPlayers[msg.sender].shareCycle!=shareCycle){
          allPlayers[msg.sender].playCount=0;
          allPlayers[msg.sender].shareCycle=shareCycle;
          insertCyclePlayer();
      }
        allPlayers[msg.sender].playCount++;
        // note we don't touch profitShare or winnings because they need to roll over cycles if unclaimed
    }
// Solidity 0.4.19
// buy into syndicate
function buyIntoSyndicate() public payable  {
        if(msg.value==0 || availableBuyInShares==0) revert();
        if(msg.value < minimumBuyIn*buyInSharePrice) revert();

        uint256 value = (msg.value/precision)*precision; // ensure precision
        uint256 allocation = value/buyInSharePrice;

        if (allocation >= availableBuyInShares){
            allocation = availableBuyInShares; // limit hit
        }
        availableBuyInShares-=allocation;
        addMember(msg.sender); // possibly add this member to the syndicate
        members[msg.sender].numShares+=allocation;
    }
// Solidity 0.4.19
// main entry point for investors/players
function invest(uint256 optionNumber) public payable {

      // Check that the number is within the range (uints are always>=0 anyway)
      assert(optionNumber <= 9);
      uint256 amount = roundIt(msg.value); // round to precision
      assert(amount >= minimumStake);

       // check for zero tie-breaker transaction
       // in this case nobody wins and investment goes into next session.
      if (block.number >= endingBlock && currentLowestCount>1 && marketOptions[currentLowest]==0){
        endSession();
        // auto invest them in the lowest market option  - reward for
        optionNumber = currentLowest;
      }

      uint256 holding = playerPortfolio[msg.sender][optionNumber];
      holding = SafeMath.add(holding, amount);
      playerPortfolio[msg.sender][optionNumber] = holding;

      marketOptions[optionNumber] = SafeMath.add(marketOptions[optionNumber],amount);

      numberOfInvestments += 1;
      totalInvested += amount;
      if (!activePlayers[msg.sender]){
                    insertPlayer(msg.sender);
                    activePlayers[msg.sender]=true;
       }

      Invest(msg.sender, optionNumber, amount, marketOptions, block.number);
      updatePlayCount(); // rank the player in leaderboard
      currentLowest = findCurrentLowest();

      // overtime and there's a winner
      if (block.number >= endingBlock && currentLowestCount==1){
          // somebody wins here.
          endSession();
      }

    }
// Solidity 0.4.19
// end invest
// find lowest option sets currentLowestCount>1 if there are more than 1 lowest
function findCurrentLowest() internal returns (uint lowestOption) {

      uint winner = 0;
      uint lowestTotal = marketOptions[0];
      currentLowestCount = 0;
      for(uint i=0;i<10;i++)
      {
          if (marketOptions [i]<lowestTotal){
              winner = i;
              lowestTotal = marketOptions [i];
              currentLowestCount = 0;
          }
         if (marketOptions [i]==lowestTotal){currentLowestCount+=1;}
      }
      return winner;
    }
// Solidity 0.4.19
// distribute winnings at the end of a session
function endSession() internal {

      uint256 sessionWinnings = 0;
      if (currentLowestCount>1){
        numberWinner = 10; // no winner
      }else{
        numberWinner = currentLowest;
      }

      // record the end of session
      for(uint j=1;j<numPlayers;j++)
      {
        if (numberWinner<10 && playerPortfolio[players[j]][numberWinner]>0){
          uint256 winningAmount =  playerPortfolio[players[j]][numberWinner];
          uint256 winnings = SafeMath.mul(winningMultiplier,winningAmount); // n times the invested amount.
          sessionWinnings+=winnings;

          allocateWinnings(players[j],winnings); // allocate winnings

          Winning(players[j], winnings, sessionNumber, numberWinner,block.number); // we can pick this up on gui
        }
        playerPortfolio[players[j]] = [0,0,0,0,0,0,0,0,0,0];
        activePlayers[players[j]]=false;
      }

      EndSession(msg.sender, sessionNumber, numberWinner, marketOptions , block.number);

      uint256 playerInvestments = totalInvested-seedInvestment;

      if (sessionWinnings>playerInvestments){
        uint256 loss = sessionWinnings-playerInvestments; // this is a loss
        if (currentSyndicateValue>=loss){
          currentSyndicateValue-=loss;
        }else{
          currentSyndicateValue = 0;
        }
      }

      if (playerInvestments>sessionWinnings){
        currentSyndicateValue+=playerInvestments-sessionWinnings; // this is a gain
      }
      resetMarket();
    }