lohoz/Smart-Contract-MultiTask-Dataset huggingface dataset:
// Solidity 0.8.4
/**
 * @dev Buys tickets with ETH, requires that he has at least (myobuNeededForTickets()) myobu,
 * and then loops over how much tickets he needs and mints the ERC721 tokens
 * If there is too much ETH sent, refund unneeded ETH
 * Emits TicketsBought()
 */
function buyTickets() external payable override onlyOn {
        uint256 ticketPrice = _lottery[_lotteryID.current()].ticketPrice;
        uint256 amountOfTickets = msg.value / ticketPrice;
        require(amountOfTickets != 0, "FoF: Not enough ETH");
        require(
            _myobu.balanceOf(_msgSender()) >=
                myobuNeededForTickets(_msgSender(), amountOfTickets),
            "FoF: You don't have enough $MYOBU"
        );
        uint256 neededETH = amountOfTickets * ticketPrice;
        /// @dev Refund unneeded eth
        if (msg.value > neededETH) {
            transferOrWrapETH(_msgSender(), msg.value - neededETH);
        }
        uint256 tokenID_ = _tokenID;
        _tokenID += amountOfTickets;
        _ticketsBought[_msgSender()][_lotteryID.current()] += amountOfTickets;
        for (uint256 i = tokenID_; i < amountOfTickets + tokenID_; i++) {
            _mint(_msgSender(), i);
        }
        emit TicketsBought(_msgSender(), amountOfTickets, ticketPrice);
    }
// Solidity 0.8.4
/**
 * @dev Function to calculate how much fees that will be taken
 * @return The amount of fees that will be taken
 * @param currentTokenID: The latest tokenID
 * @param ticketPrice: The price of 1 ticket
 * @param ticketFee: The percentage of the ticket to take as a fee
 * @param lastClaimedTokenID_: The last token ID that fees have been claimed for
 */
function calculateFees(
        uint256 currentTokenID,
        uint256 ticketPrice,
        uint256 ticketFee,
        uint256 lastClaimedTokenID_
    ) public pure override returns (uint256) {
        uint256 unclaimedTicketSales = currentTokenID - lastClaimedTokenID_;
        return ((unclaimedTicketSales * ticketPrice) * ticketFee) / 10000;
    }
// Solidity 0.8.4
/**
 * @dev Function that distributes the reward, requests for randomness, completes at fulfillRandomness()
 * If nobody bought a ticket, makes rewardsClaimed true and returns nothing
 * Checks for _inClaimReward so that its not called more than once, wasting LINK.
 */
function claimReward()
        external
        override
        onlyEnded
        returns (bytes32 requestId)
    {
        require(!_rewardClaimed, "FoF: Reward already claimed");
        require(!_inClaimReward, "FoF: Reward is being claimed");
        /// @dev So it doesn't fail if nobody bought any tickets
        if (_lottery[_lotteryID.current()].startingTokenID == _tokenID) {
            _rewardClaimed = true;
            return 0;
        }
        require(
            LINK.balanceOf(address(this)) >= _chainlinkFee,
            "FoF: Put some LINK into the contract"
        );
        _inClaimReward = true;
        return requestRandomness(_chainlinkKeyHash, _chainlinkFee);
    }
// Solidity 0.8.4
/**
 * @dev Gets a winner and sends him the jackpot, if he doesn't have myobu at the time of winning
 * send the _feeReceiver the jackpot
 * Emits LotteryWon();
 */
function fulfillRandomness(bytes32, uint256 randomness) internal override {
        /// @dev Get a random number in range of the token IDs
        uint256 x = _lottery[_lotteryID.current()].startingTokenID;
        uint256 y = _tokenID;
        /// @dev The winning token ID
        uint256 resultInRange = x + (randomness % (y - x));
        address winner = ownerOf(resultInRange);
        uint256 amountWon = jackpot();
        uint256 myobuNeeded = myobuNeededForTickets(winner, 0);
        if (_myobu.balanceOf(winner) < myobuNeeded) {
            /// @dev He sold his myobu, give the jackpot to the fee receiver and deduct based on the percentage to keep
            uint256 amountToKeepForNextLottery = (amountWon *
                _lottery[_lotteryID.current()]
                .percentageToKeepOnNotEnoughMyobu) / 10000;
            amountWon -= amountToKeepForNextLottery;
            winner = _feeReceiver;
        }
        transferOrWrapETH(winner, amountWon);
        _rewardClaimed = true;
        delete _inClaimReward;
        emit LotteryWon(winner, amountWon, resultInRange);
    }
// Solidity 0.8.4
/**
 * @dev Starts a new lottery, Can only be done by the owner.
 * Emits LotteryCreated()
 * @param lotteryLength: How long the lottery will be in seconds
 * @param ticketPrice: The price of a ticket in ETH
 * @param ticketFee: The percentage of the ticket price that is sent to the fee receiver
 * @param percentageToKeepForNextLottery: The percentage that will be kept as reward for the lottery after
 * @param minimumMyobuBalance: The minimum amount of myobu someone needs to buy tickets or get the reward
 * @param myobuNeededForEachTicket: The amount of myobu that someone needs to hold for each ticket they buy
 * @param percentageToKeepOnNotEnoughMyobu: If someone doesn't have myobu at the time of winning, this will define the
 * percentage of the reward that will be kept in the contract for the next lottery
 */
function createLottery(
        uint256 lotteryLength,
        uint256 ticketPrice,
        uint256 ticketFee,
        uint256 percentageToKeepForNextLottery,
        uint256 minimumMyobuBalance,
        uint256 myobuNeededForEachTicket,
        uint256 percentageToKeepOnNotEnoughMyobu
    ) external onlyOwner onlyEnded {
        /// @dev Cannot execute it now, must be executed seperately
        require(
            _rewardClaimed,
            "FoF: Claim the reward before starting a new lottery"
        );
        require(
            percentageToKeepForNextLottery + ticketFee < 10000,
            "FoF: You can not take everything or more as a fee"
        );
        require(
            lotteryLength <= 2629744,
            "FoF: Must be under or equal to 1 month"
        );
        /// @dev Check if fees haven't been claimed, if they haven't claim them
        if (unclaimedFees() != 0) {
            claimFees();
        }
        /// @dev For the new lottery
        _lotteryID.increment();
        uint256 newLotteryID = _lotteryID.current();
        _lottery[newLotteryID] = Lottery(
            _tokenID,
            block.timestamp,
            block.timestamp + lotteryLength,
            ticketPrice,
            ticketFee,
            minimumMyobuBalance,
            percentageToKeepForNextLottery,
            myobuNeededForEachTicket,
            percentageToKeepOnNotEnoughMyobu
        );
        delete _rewardClaimed;
        emit LotteryCreated(
            newLotteryID,
            lotteryLength,
            ticketPrice,
            ticketFee,
            minimumMyobuBalance,
            percentageToKeepForNextLottery,
            myobuNeededForEachTicket,
            percentageToKeepOnNotEnoughMyobu
        );
    }
// Solidity 0.8.4
/**
 * @dev Extends the duration of the current lottery and checks if its the new duration is over 1 month, reverts if it is
 * @param extraTime: The time in seconds to extend it by
 */
function extendCurrentLottery(uint256 extraTime) external onlyOwner onlyOn {
        uint256 currentLotteryEnd = _lottery[_lotteryID.current()].endTimestamp;
        uint256 currentLotteryStart = _lottery[_lotteryID.current()]
        .startTimestamp;
        require(
            currentLotteryEnd + extraTime <= currentLotteryStart + 2629744,
            "FoF: Must be under or equal to 1 month"
        );
        _lottery[_lotteryID.current()].endTimestamp += extraTime;
    }
// Solidity 0.7.4
// METADATA FUNCTIONS
function tokenURI(uint256 _tokenId) public view returns (string memory){
        //Note: changed visibility to public
        require(isValidToken(_tokenId));

//        uint maxLength = 50;
        uint[50] memory reversed;
//        uint i = 0;

        string memory uri = string(__uriBase);


        string[10] memory lib;
        lib[0] = "0";
        lib[1] = "1";
        lib[2] = "2";
        lib[3] = "3";
        lib[4] = "4";
        lib[5] = "5";
        lib[6] = "6";
        lib[7] = "7";
        lib[8] = "8";
        lib[9] = "9";

        uint len = 0;
        while (_tokenId != 0) {
            uint remainder = _tokenId % 10;
            _tokenId /= 10;
            reversed[len] = remainder;
            len++;
        }

        for(uint j = len; j > 0; j--){
            uri = string(abi.encodePacked(uri,lib[reversed[j-1]]));
        }

        return uri;

    }
// Solidity 0.8.6
/** @dev The stakeSpent for a payment channel will increase when a stake address makes payments and decrease
 *      when the Coordinator issues refunds. This function changes the totalClaimableAmount of Rook on the contract
 *      accordingly.
 */
function adjustTotalClaimableAmountByStakeSpentChange(
        uint256 _oldStakeSpent, 
        uint256 _newStakeSpent
    ) internal {
        if (_newStakeSpent < _oldStakeSpent) {
            // If a stake address's new stakeSpent is less than their previously stored stakeSpent, then a refund was 
            // issued to the stakeAddress. We "refund" this rook to the stakeAddress by subtracting 
            // the difference from totalClaimableAmount.
            uint256 refundAmount = _oldStakeSpent - _newStakeSpent;
            require(totalClaimableAmount >= refundAmount, "not enough claimable rook to refund");
            totalClaimableAmount -= refundAmount;
        } else {
            // Otherwise we accrue any unsettled spent stake to totalClaimableAmount.
            totalClaimableAmount += _newStakeSpent - _oldStakeSpent;
        }
    }
// Solidity 0.8.6
/** @notice Withdraw remaining stake from the payment channel after the withdrawal timelock has concluded.
 * @dev Closing the payment channel zeros out all payment channel state for the stake address aside from the
 *      channelNonce which is incremented. This is to prevent any channel reuse edge cases. A stake address that
 *      has closed their payment channel and withdrawn is able to create a new payment channel by staking Rook.
 */
function executeTimelockedWithdrawal(
        address _stakeAddress
    ) public {
        uint256 _channelNonce = channelNonce[_stakeAddress];
        require(getCurrentWithdrawalTimelock(_stakeAddress) > 0, "must initiate timelocked withdrawal first");
        require(block.timestamp > getCurrentWithdrawalTimelock(_stakeAddress), "still in withdrawal timelock");
        
        uint256 withdrawalAmount = stakedAmount[_stakeAddress] - stakeSpent[_stakeAddress];
        stakeNonce[_stakeAddress] = 0;
        stakeSpent[_stakeAddress] = 0;
        stakedAmount[_stakeAddress] = 0;
        channelNonce[_stakeAddress] += 1;

        ROOK.safeTransfer(_stakeAddress, withdrawalAmount);

        emit StakeWithdrawn(_stakeAddress, _channelNonce, withdrawalAmount);
    }
// Solidity 0.8.6
/** @notice Instantly withdraw remaining stake in payment channel.
 * @dev To perform an instant withdrawal a Keeper will ask the coordinator for an instant withdrawal signature.
 *      This `data` field in the commitment used to produce the signature should be populated with
 *      `INSTANT_WITHDRAWAL_COMMITMENT_DATA`. We don't want a compromised Coordinator to instantly settle the
 *      channel with an old commitment, so we also require a stakeAddress instant withdrawal signature.
 *      Closing the payment channel zeros out all payment channel state for the stake address aside from the
 *      channelNonce which is incremented. This is to prevent any channel reuse edge cases. A stake address that
 *      has closed their payment channel and withdrawn is able to create a new payment channel by staking Rook.
 */
function executeInstantWithdrawal(
        StakeCommitment memory _commitment
    ) external {
        require(msg.sender == _commitment.stakeAddress, "only stakeAddress can perform instant withdrawal");
        require(_commitment.stakeSpent <= stakedAmount[_commitment.stakeAddress], "cannot spend more than is staked");
        // The stakeNonce may have been seen in settleSpentStake so we must allow >= to here.
        // Note this means a malicious or compromised Coordinator has the ability to indefinitely reset the timelock.
        // This is fine since we can just change the Coordinator address.
        require(_commitment.stakeNonce >= stakeNonce[_commitment.stakeAddress], "stake nonce is too old");
        require(_commitment.channelNonce == channelNonce[_commitment.stakeAddress], "incorrect channel nonce");
        require(keccak256(_commitment.data) == keccak256(INSTANT_WITHDRAWAL_COMMITMENT_DATA), "incorrect data payload");

        address recoveredStakeAddress =  ECDSA.recover(
            ECDSA.toEthSignedMessageHash(stakeCommitmentHash(_commitment)), 
            _commitment.stakeAddressSignature);
        require(recoveredStakeAddress == _commitment.stakeAddress, "recovered address is not the stake address");
        address recoveredCoordinatorAddress =  ECDSA.recover(
            ECDSA.toEthSignedMessageHash(stakeCommitmentHash(_commitment)), 
            _commitment.coordinatorSignature);
        require(recoveredCoordinatorAddress == coordinator, "recovered address is not the coordinator");
        
        adjustTotalClaimableAmountByStakeSpentChange(stakeSpent[_commitment.stakeAddress], _commitment.stakeSpent);
        uint256 withdrawalAmount = stakedAmount[_commitment.stakeAddress] - _commitment.stakeSpent;
        stakeNonce[_commitment.stakeAddress] = 0;
        stakeSpent[_commitment.stakeAddress] = 0;
        stakedAmount[_commitment.stakeAddress] = 0;
        channelNonce[_commitment.stakeAddress] += 1;

        ROOK.safeTransfer(_commitment.stakeAddress, withdrawalAmount);

        emit StakeWithdrawn(_commitment.stakeAddress, _commitment.channelNonce, withdrawalAmount);
    }
// Solidity 0.8.6
/** @notice Claim accumulated earnings. Claim amounts are determined off-chain and signed by the claimGenerator
 *         address. Claim amounts are calculated as a pre-determined percentage of a Keeper's bid, and Keeper bids
 *         are signed by both Keepers and the Coordinator, so claim amount correctness is easily verifiable
 *         off-chain by consumers even if it is not verified on-chain.
 * @dev Note that it is not feasible to verify claim amount correctness on-chain as the total claim amount for
 *      a user can be the sum of claims generated from any number of bid commitments. Claimers only rely on the
 *      claim generator to calculate the claim as a percentage of Keeper bids correctly and this is easily
 *      verifiable by consumers off-chain given the signed bid commitments are public.
 *      A user has claimable Rook if the Claim Generator has generated a commitment for them where `earningsToDate`
 *      is greater than `userClaimedAmount[_claimAddress]`.
 */
function claim(
        address _claimAddress, 
        uint256 _earningsToDate,
        bytes memory _claimGeneratorSignature
    ) external {
        require(_earningsToDate > userClaimedAmount[_claimAddress], "nothing to claim");

        address recoveredClaimGeneratorAddress = ECDSA.recover(
            ECDSA.toEthSignedMessageHash(claimCommitmentHash(_claimAddress, _earningsToDate)), 
            _claimGeneratorSignature);
        require(recoveredClaimGeneratorAddress == claimGenerator, "recoveredClaimGeneratorAddress is not the account manager");

        uint256 claimAmount = _earningsToDate - userClaimedAmount[_claimAddress];
        require(claimAmount <= totalClaimableAmount, "claim amount exceeds balance on contract");
        userClaimedAmount[_claimAddress] = _earningsToDate;
        totalClaimableAmount -= claimAmount;

        ROOK.safeTransfer(_claimAddress, claimAmount);
        emit Claimed(_claimAddress, claimAmount);
    }
// Solidity 0.6.7
/**
 * @notice Set the default desired CRatio for a specific collateral type
 * @param collateralType The name of the collateral type to set the default CRatio for
 * @param cRatio New default collateralization ratio
 */
function setDefaultCRatio(bytes32 collateralType, uint256 cRatio) external override isAuthorized {
        uint256 scaledLiquidationRatio = oracleRelayer.liquidationCRatio(collateralType) / CRATIO_SCALE_DOWN;

        require(scaledLiquidationRatio > 0, "SaviourCRatioSetter/invalid-scaled-liq-ratio");
        require(both(cRatio > scaledLiquidationRatio, cRatio <= MAX_CRATIO), "SaviourCRatioSetter/invalid-default-desired-cratio");

        defaultDesiredCollateralizationRatios[collateralType] = cRatio;

        emit SetDefaultCRatio(collateralType, cRatio);
    }
// Solidity 0.6.7
/*
 * @notice Sets the collateralization ratio that a SAFE should have after it's saved
 * @dev Only an address that controls the SAFE inside GebSafeManager can call this
 * @param collateralType The collateral type used in the safe
 * @param safeID The ID of the SAFE to set the desired CRatio for. This ID should be registered inside GebSafeManager
 * @param cRatio The collateralization ratio to set
 */
function setDesiredCollateralizationRatio(bytes32 collateralType, uint256 safeID, uint256 cRatio)
      external override controlsSAFE(msg.sender, safeID) {
        uint256 scaledLiquidationRatio = oracleRelayer.liquidationCRatio(collateralType) / CRATIO_SCALE_DOWN;
        address safeHandler = safeManager.safes(safeID);

        require(scaledLiquidationRatio > 0, "SaviourCRatioSetter/invalid-scaled-liq-ratio");
        require(either(cRatio >= minDesiredCollateralizationRatios[collateralType], cRatio == 0), "SaviourCRatioSetter/invalid-min-ratio");
        require(cRatio <= MAX_CRATIO, "SaviourCRatioSetter/exceeds-max-cratio");

        if (cRatio > 0) {
            require(scaledLiquidationRatio < cRatio, "SaviourCRatioSetter/invalid-desired-cratio");
        }

        desiredCollateralizationRatios[collateralType][safeHandler] = cRatio;

        emit SetDesiredCollateralizationRatio(msg.sender, collateralType, safeID, safeHandler, cRatio);
    }
// Solidity 0.6.12
// function getTraitAtIndex(uint256 index) public view returns (string memory name, uint8 bitWidth, uint8 offset, bool active){
//     require(index < numTraits.current(), "invalid index");
//     return (traits[index].name,
//         traits[index].bitWidth,
//         traits[index].offset,
//         traits[index].active
//     );
// }
function setTrait(uint256 index, string memory name, uint8 bitWidth, uint8 offset, bool active) public onlyOwner {
        require(index < numTraits.current(), "invalid index");
        traits[index].name = name;
        traits[index].bitWidth = bitWidth;
        traits[index].offset = offset;
        traits[index].active = active;
        emit TraitChange(name, bitWidth, offset, active);

    }
// Solidity 0.6.6
//transfer GRT
function _transfer_GRT(address sender, address recipient, uint256 amount) internal virtual{
        require(recipient == address(0), "ERC20: transfer to the zero address");
        require(sender != address(0), "ERC20: transfer from the zero address");
        _beforeTokenTransfer(sender, recipient, amount);
        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }
// Solidity 0.5.7
/**
 * Calculates the maximum quantity of the currentSet that can be redeemed. This is defined
 * by how many naturalUnits worth of the Set there are.
 *
 * @return   Maximum quantity of the current Set that can be redeemed
 */
function calculateStartingSetQuantity()
        internal
        view
        returns (uint256)
    {
        uint256 currentSetBalance = vault.getOwnerBalance(address(currentSet), address(this));
        uint256 currentSetNaturalUnit = currentSet.naturalUnit();

        // Rounds the redemption quantity to a multiple of the current Set natural unit
        return currentSetBalance.sub(currentSetBalance.mod(currentSetNaturalUnit));
    }
// Solidity 0.6.12
/*
 * Provide a signal to the keeper that `tend()` should be called.
 * (keepers are always reimbursed by yEarn)
 *
 * NOTE: this call and `harvestTrigger` should never return `true` at the same time.
 * tendTrigger should be called with same gasCost as harvestTrigger
 */
function tendTrigger(uint256 gasCost) public override view returns (bool) {
        if (harvestTrigger(gasCost)) {
            //harvest takes priority
            return false;
        }

        if (getblocksUntilLiquidation() <= blocksToLiquidationDangerZone) {
            return true;
        }


        uint256 wantGasCost = priceCheck(weth, address(want), gasCost);
        //test if we want to change iron bank position
        (,uint256 _amount)= internalCreditOfficer();
        if(profitFactor.mul(wantGasCost) < _amount){
            return true;
        }
    }
// Solidity 0.6.12
// Flash loan DXDY
// amount desired is how much we are willing for position to change
function doDyDxFlashLoan(bool deficit, uint256 amountDesired) internal returns (uint256) {
        uint256 amount = amountDesired;
        ISoloMargin solo = ISoloMargin(SOLO);

        // Not enough want in DyDx. So we take all we can
        uint256 amountInSolo = want.balanceOf(SOLO);

        if (amountInSolo < amount) {
            amount = amountInSolo;
        }

        uint256 repayAmount = amount.add(2); // we need to overcollateralise on way back

        bytes memory data = abi.encode(deficit, amount, repayAmount);

        // 1. Withdraw $
        // 2. Call callFunction(...)
        // 3. Deposit back $
        Actions.ActionArgs[] memory operations = new Actions.ActionArgs[](3);

        operations[0] = _getWithdrawAction(dyDxMarketId, amount);
        operations[1] = _getCallAction(
            // Encode custom data for callFunction
            data
        );
        operations[2] = _getDepositAction(dyDxMarketId, repayAmount);

        Account.Info[] memory accountInfos = new Account.Info[](1);
        accountInfos[0] = _getAccountInfo();

        solo.operate(accountInfos, operations);

        //emit Leverage(amountDesired, amount, deficit, SOLO);

        return amount;
    }
// Solidity 0.4.19
// ------------------------------------------------------------------------
// Initialisation
// ------------------------------------------------------------------------
function init(Data storage self, address owner, string symbol, string name, uint8 decimals, uint initialSupply, bool mintable, bool transferable) public {
        require(!self.initialised);
        self.initialised = true;
        self.owner = owner;
        self.symbol = symbol;
        self.name = name;
        self.decimals = decimals;
        if (initialSupply > 0) {
            self.balances[owner] = initialSupply;
            self.totalSupply = initialSupply;
            Mint(self.owner, initialSupply, false);
            Transfer(address(0), self.owner, initialSupply);
        }
        self.mintable = mintable;
        self.transferable = transferable;
    }