lohoz/Smart-Contract-MultiTask-Dataset huggingface dataset:
// Solidity 0.6.12
// user register referral address
function register(address _refer) public {
        require(msg.sender != _refer, "ERROR: address cannot refer itself");
        require(referrals[msg.sender] == address(0), "ERROR: already set refer address");

        // owner address is the root of references tree
        if (_refer != owner() && !getWhiteListRoot(_refer)) {
            require(referrals[_refer] != address(0), "ERROR: invalid refer address");
        }

        // update reference tree
        referrals[msg.sender] = _refer;

        emit LinkCreated(msg.sender, _refer);
    }
// Solidity 0.6.12
// get total user unstake requested amount
function getUserPendingUnstake(uint256 _pool, address _user) public view returns(uint256) {
        uint256 amount;
        for (uint256 i=0; i<unstakeRequests[_pool].length; i++) {
            if (unstakeRequests[_pool][i].user == _user && !unstakeRequests[_pool][i].processed) {
                amount = amount.add(unstakeRequests[_pool][i].amount);
            }
        }
        return amount;
    }
// Solidity 0.6.12
// estimate amount of reward token for harvest
function estimatePayout(uint256 _pool, uint256 _percent, uint256 _rate) public view returns(uint256) {
        uint256 estimateAmount;
        uint256 decimals = 18;
        if (_pool != 0) {
            decimals = ERC20Helper.getDecimals(pools[_pool].token);
        }

        for (uint256 i=0; i<usersList[_pool].length; i++) {
            address user = usersList[_pool][i];

            // calculate profit
            uint256 profitAmount = getUserStakedBalance(_pool, user)
                .mul(_percent)
                .mul(_rate)
                .div(100);
            profitAmount = profitAmount.mul(10**(18 - decimals)).div(1e12);

            estimateAmount = estimateAmount.add(profitAmount);

            // estimate payout amount for references
            Controller iController = Controller(controller);
            uint256 maxLevel = iController.getMarketingMaxLevel();
            uint256 level;
            while(level < maxLevel) {
                address parent = iController.getReferenceParent(user, level);
                if (parent == address(0)) break;

                if (getUserStakedBalance(_pool, parent) > 0) {
                    uint256 percent = iController.getMarketingLevelValue(level);
                    uint256 referProfitAmount = profitAmount.mul(percent).div(100).div(1e6);
                    estimateAmount = estimateAmount.add(referProfitAmount);
                }

                level++;
            }
        }

        return estimateAmount;
    }
// Solidity 0.6.12
// update profit for reference parents
function payoutReference(uint256 _pool, address _child, uint256 _amount) internal returns(uint256) {
        uint256 totalPayout;
        Controller iController = Controller(controller);
        uint256 maxLevel = iController.getMarketingMaxLevel();
        uint256 level;
        while(level < maxLevel) {
            address parent = iController.getReferenceParent(_child, level);
            if (parent == address(0)) break;

            if (getUserStakedBalance(_pool, parent) > 0) {
                uint256 percent = iController.getMarketingLevelValue(level);
                uint256 referProfitAmount = _amount.mul(percent).div(100).div(1e6);

                increaseUserPendingReward(_pool, parent, referProfitAmount);
                totalPayout = totalPayout.add(referProfitAmount);
            }

            level++;
        }

        return totalPayout;
    }
// Solidity 0.6.12
// deposit amount of ETH or tokens to contract
// user MUST call approve function in Token contract to approve _value for this contract
//
// after deposit, _value added to staking balance
// after one payout action, staking balance will be moved to staked balance
function stake(uint256 _pool, uint256 _value) public payable {
        if (_pool == 0) {
            increaseUserStakingBalance(_pool, msg.sender, msg.value);

            TransferHelper.safeTransferETH(admin, msg.value);

            emit Stake(msg.sender, _pool, msg.value);
        } else {
            TransferHelper.safeTransferFrom(pools[_pool].token, msg.sender, address(this), _value);
            TransferHelper.safeTransfer(pools[_pool].token, admin, _value);

            increaseUserStakingBalance(_pool, msg.sender, _value);

            emit Stake(msg.sender, _pool, _value);
        }

        bool isListed;
        for (uint256 i=0; i<usersList[_pool].length; i++) {
            if (usersList[_pool][i] == msg.sender) isListed = true;
        }

        if (!isListed) {
            usersList[_pool].push(msg.sender);
        }
    }
// Solidity 0.6.12
// request unstake amount of ETH or tokens
// user can only request unstake in staked balance
function unstake(uint256 _pool, uint256 _value) public {
        uint256 stakedBalance = getUserStakedBalance(_pool, msg.sender);
        uint256 requestedAmount = getUserPendingUnstake(_pool, msg.sender);
        require(_value + requestedAmount <= stakedBalance, "ERROR: insufficient balance");

        unstakeRequests[_pool].push(UnstakeRequest({
            user: msg.sender,
            amount: _value,
            processed: false
        }));

        emit Unstake(msg.sender, _pool, _value);
    }
// Solidity 0.6.12
// payout function
// called only by admin
// param @_percent: present amount of reward based on stakedBalance of user
// param @_rate: how many reward token for each deposit token
//  ex: ? BVA = 1 ETH
// _percent & _rate must be multiple by 1e6
//
// 1. process user staked balance
// 2. move user staking balance to staked balance
function payout(uint256 _pool, uint256 _percent, uint256 _rate) public onlyAdmin {
        uint256 totalPayoutReward;
        uint256 decimals = 18;
        if (_pool != 0) {
            decimals = ERC20Helper.getDecimals(pools[_pool].token);
        }

        for (uint256 i=0; i<usersList[_pool].length; i++) {
            address user = usersList[_pool][i];

            // calculate profit
            uint256 profitAmount = getUserStakedBalance(_pool, user)
                .mul(_percent)
                .mul(_rate)
                .div(100);
            profitAmount = profitAmount.mul(10**(18 - decimals)).div(1e12);
            totalPayoutReward = totalPayoutReward.add(profitAmount);

            // add profit to pending reward
            increaseUserPendingReward(_pool, user, profitAmount);

            // move user staking balance to staked balance
            increaseUserStakedBalance(_pool, user, getUserStakingBalance(_pool, user));
            decreaseUserStakingBalance(_pool, user, getUserStakingBalance(_pool, user));

            // calculate profit for reference users
            // double check vs controller
            uint256 totalReferencePayout = payoutReference(_pool, user, profitAmount);
            totalPayoutReward = totalPayoutReward.add(totalReferencePayout);
        }

        TransferHelper.safeTransferFrom(token, msg.sender, address(this), totalPayoutReward);

        emit Payout(msg.sender, _pool, _percent, _rate);
    }
// Solidity 0.6.12
// process unstake requests
// admin call this function and send ETH or tokens to process
// this function check requests all auto process each request
function processUnstake(uint256 _pool, uint256 _amount) public payable onlyAdmin {
        if (_pool == 0) {
            uint256 tokenBalance = address(this).balance;

            // process until tokenBalance = 0
            for (uint256 i=0; i<unstakeRequests[_pool].length; i++) {
                if (unstakeRequests[_pool][i].amount <= tokenBalance && !unstakeRequests[_pool][i].processed) {
                    address user = unstakeRequests[_pool][i].user;
                    TransferHelper.safeTransferETH(user, unstakeRequests[_pool][i].amount);
                    tokenBalance = tokenBalance.sub(unstakeRequests[_pool][i].amount);
                    decreaseUserStakedBalance(_pool, user, unstakeRequests[_pool][i].amount);
                    setProcessedUnstakeRequest(_pool, i);
                }
            }

            emit UnstakeProcessed(msg.sender, _pool, msg.value);
        } else {
            TransferHelper.safeTransferFrom(pools[_pool].token, getAdmin(), address(this), _amount);
            uint256 tokenBalance = ERC20Helper.getBalance(pools[_pool].token, address(this));

            for (uint256 i=0; i<unstakeRequests[_pool].length; i++) {
                if (unstakeRequests[_pool][i].amount <= tokenBalance && !unstakeRequests[_pool][i].processed) {
                    address user = unstakeRequests[_pool][i].user;
                    // transfer token from contract -> user
                    TransferHelper.safeTransfer(pools[_pool].token, user, unstakeRequests[_pool][i].amount);
                    tokenBalance = tokenBalance.sub(unstakeRequests[_pool][i].amount);

                    decreaseUserStakedBalance(_pool, user, unstakeRequests[_pool][i].amount);
                    setProcessedUnstakeRequest(_pool, i);
                }
            }

            emit UnstakeProcessed(msg.sender, _pool, _amount);
        }
    }
// Solidity 0.7.0
//MulDiv functions : source https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1
function mulDiv(uint x, uint y, uint z) public pure returns (uint) {
          (uint l, uint h) = fullMul (x, y);
          assert (h < z);
          uint mm = mulmod(x, y, z);
          if (mm > l) h -= 1;
          l -= mm;
          uint pow2 = z & -z;
          z /= pow2;
          l /= pow2;
          l += h * ((-pow2) / pow2 + 1);
          uint r = 1;
          r *= 2 - z * r;
          r *= 2 - z * r;
          r *= 2 - z * r;
          r *= 2 - z * r;
          r *= 2 - z * r;
          r *= 2 - z * r;
          r *= 2 - z * r;
          r *= 2 - z * r;
          return l * r;
    }
// Solidity 0.7.0
//Required for MulDiv
function fullMul(uint x, uint y) private pure returns (uint l, uint h) {
          uint mm = mulmod(x, y, uint (-1));
          l = x * y;
          h = mm - l;
          if (mm < l) h -= 1;
    }
// Solidity 0.7.0
//Redeem lotto cards
function redeemLotto(uint256 _cardID) public {

        //Check ownership of card
        require(crafterContract.balanceOf(msg.sender, _cardID) > 0, "You do not own this card");
        //Make sure card is a lotto card
        require(_cardID < 5, "Card is not a lotto card");

        uint256 _cardAmount = 1;
        string memory _collectionName;

        if(_cardID < 3) {
            _collectionName = "Ethereum Lotto";
            if(_cardID == 1) {
                _cardAmount = 10;
                require(crafterContract.balanceOf(msg.sender, _cardID) >= _cardAmount, "10 common cards required to craft");
            } else {
                require(crafterContract.balanceOf(msg.sender, _cardID) >= _cardAmount, "1 rare card required to craft");
            }
        } else {
            _collectionName = "LYNC Token Lotto";
            if(_cardID ==  3) {
                _cardAmount = 10;
                require(crafterContract.balanceOf(msg.sender, _cardID) >= _cardAmount, "10 common cards required to craft");
            } else {
                require(crafterContract.balanceOf(msg.sender, _cardID) >= _cardAmount, "1 rare card required to craft");
            }
        }

        //Craft reward card
        crafterContract.craftRewardCard(msg.sender, _cardID, _collectionName);
        //Burn card(s)
        crafterContract.burnCard(msg.sender, _cardID, _cardAmount);
    }
// Solidity 0.7.0
//Redeem reward card
function redeemReward(uint256 _cardID) public {

        //Check ownership of card
        require(crafterContract.balanceOf(msg.sender, _cardID) > 0, "You do not own this card");

        //Grab card data
        (,uint256 cardType,,,uint256 _redeemLeft,uint256 _redeemInterval,uint256 _redeemLastTimeStamp,uint256 _tokenReward,uint256 _percentageRedeem) = crafterContract.cards(_cardID);

        //Check card last redeem timestamp against its interval
        require(block.timestamp > (_redeemLastTimeStamp + _redeemInterval.mul(oneDay)), "This card has already been redeemed this interval, wait until reset");
         //Make sure this is is not a booster card
        require(cardType != 3, "Booster cards do not have any rewards associated with them");

        //Update or burn card
        if(cardType != 2) {
            //Burn the card
            crafterContract.burnCard(msg.sender, _cardID, 1);
        } else {
            require(_redeemLeft > 0, "No redeems available on this card");
            crafterContract.updateCardStats(_cardID);
        }

        //Token redeem
        if(_tokenReward > 0) {
            //Send token reward
            require(tokenContract.transfer(msg.sender, _tokenReward.mul(SCALAR)));
        }

        //Percentage redeem
        if(_percentageRedeem > 0) {

            //Get balance from staking contract
            (uint256 _stakedTokens,,) = stakingContract.stakerInformation(msg.sender);
            //Calculate percentage
            uint256 _percentageReward = mulDiv(_stakedTokens, _percentageRedeem, 100);
            //Send token reward
            require(tokenContract.transfer(msg.sender, _percentageReward));
        }
    }
// Solidity 0.4.18
//21m coins total
//reward begins at 50 and is cut in half every reward era (as tokens are mined)
function getMiningReward() public constant returns (uint) {
        //once we get half way thru the coins, only get 25 per block

         //every reward era, the reward amount halves.

         return (50 * 10**uint(decimals) ).div( 2**rewardEra ) ;

    }
// Solidity 0.5.17
// overridable for testing
function getReserves(address tokenA, address tokenB)
        internal
        view
        returns (uint256 reserveA, uint256 reserveB)
    {
        (address token0, ) = UniswapV2Library.sortTokens(tokenA, tokenB);
        (uint256 reserve0, uint256 reserve1, ) =
            IUniswapV2Pair(
                UniswapV2Library.pairFor(UNISWAP_FACTORY, tokenA, tokenB)
            )
                .getReserves();
        (reserveA, reserveB) = tokenA == token0
            ? (reserve0, reserve1)
            : (reserve1, reserve0);
    }
// Solidity 0.8.4
// mLoots deposited to this contract CANNOT be returned!
function mLootMultiDeposit(uint256[] memory mLootId) external payable nonReentrant{
        require(depositPrice * mLootId.length <= msg.value, "Ether value sent is not correct");
        for (uint256 i = 0; i < mLootId.length; i++){
            _deposit(mLootId[i]);
        }
        emit DepositMulti(_msgSender(), mLootId);
    }
// Solidity 0.8.7
/// @notice Returns the NFT metadata.
/// @param tokenId The token id that we want to get its metadata.
/// @return string, Concatenated baseURI, tokenName(Same as tokenId), json, Which results in url pointing to the token metadata.
function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "HYPERSLOTHS: URI query for nonexistent token"
        );

        string memory baseURI = _baseURI();
        string memory tokenName = Strings.toString(tokenId);
        string memory json = ".json";
        return
            bytes(baseURI).length > 0
                ? string(abi.encodePacked(baseURI, tokenName, json))
                : "";
    }
// Solidity 0.8.7
/// @notice Same as mint function but without validations.
/// @dev Can be called only by the owner and can't mint more than 40 at a time.
/// @param _to The address that is getting the NFT.
/// @param amount The amount the address is allowed to mint.
/// @param proof A hash, proof that this user is verified in merkle tree.
function mintFreeNFT(
        address _to,
        uint256 amount,
        bytes32[] memory proof
    ) public onlyOwner {
        require(amount <= 40, "Cant Mint More Than 40 NFTs At A Time.");
        require(
            validateUser(proof, _leaf(_to, amount), freeMintMerkleRoot),
            "User Is Not In The Free Mint List."
        );
        for (uint256 i = 0; i < amount; i++) {
            uint256 newItemId = totalSupply() + 1;
            _safeMint(_to, newItemId);
        }
        // Incrementing the correct counter by the amount after each mint loop.
        freeMintsAmount[_to] += amount;
    }
// Solidity 0.8.7
/// @notice Get The NFT Ids Owned By An Address.
/// @param _address The owner of the nfts.
/// @return uint256[], Array of token ids that the address owns.
function getTokensByAddress(address _address)
        public
        view
        returns (uint256[] memory)
    {
        uint256 amount = balanceOf(_address);
        uint256[] memory tokens = new uint256[](amount);
        for (uint256 i = 0; i < amount; i++) {
            uint256 token = tokenOfOwnerByIndex(_address, i);
            tokens[i] = token;
        }
        return tokens;
    }
// Solidity 0.8.7
/// @notice Check if the caller is in whitelist or freemint list.
/// @param proof MerkleTree proof that the user is verified.
/// @param leaf MerkleTree hash that is then verified by the root.
/// @return bool, True - User is verified, False - User is not verified.
function validateUser(
        bytes32[] memory proof,
        bytes32 leaf,
        bytes32 root
    ) public view returns (bool) {
        require(
            root == whiteListMerkleRoot || root == freeMintMerkleRoot,
            "root is not valid"
        );
        return MerkleProof.verify(proof, root, leaf);
    }
// Solidity 0.7.6
// Add multiple pools for one victim
function addBulk(Victim _victim, uint256[] memory victimPids) external onlyOwner {
        for (uint i = 0; i < victimPids.length; i++) {
            poolInfo.push(PoolInfo({
                victim: _victim,
                victimPoolId: victimPids[i],
                lastUpdateBlock: 0,
                accWethPerShare: 0,
                wethAccumulator: 0,
                rewardRate: 0,
                periodFinish: 0,
                basePoolShares: 0,
                baseDeposits: 0
            }));
        }
    }
// Solidity 0.7.6
// WETH reward per staked share
function wethPerShare(uint256 _pid) public view returns (uint256) {
        PoolInfo storage pool = poolInfo[_pid];
        uint256 totalStaked = pool.victim.lockedAmount(pool.victimPoolId);
        if (totalStaked == 0) {
            return pool.accWethPerShare;
        }
        return
            pool.accWethPerShare.add(
                lastTimeRewardApplicable(_pid)
                    .sub(pool.lastUpdateBlock)
                    .mul(pool.rewardRate)
                    .mul(1e18)
                    .div(totalStaked)
            );
    }
// Solidity 0.7.6
// Withdraw in case of emergency. No rewards will be claimed.
function emergencyWithdraw(uint256 pid) external nonReentrant {
        PoolInfo storage pool = poolInfo[pid];
        UserInfo storage user = userInfo[pid][msg.sender];
        pool.victim.withdraw(pool.victimPoolId, user.amount);
        pool.victim.lockableToken(pool.victimPoolId).safeTransfer(address(msg.sender), user.amount);
        emit EmergencyWithdraw(msg.sender, pid, user.amount);
        user.amount = 0;
        user.rewards = 0;
        user.rewardDebt = 0;
        user.poolShares = 0;
    }
// Solidity 0.6.12
/// @dev Return the LP token for the token pairs (can be in any order)
/// @param tokenA Token A to get LP token
/// @param tokenB Token B to get LP token
function getAndApprovePair(address tokenA, address tokenB) public returns (address) {
    address lp = pairs[tokenA][tokenB];
    if (lp == address(0)) {
      lp = factory.getPair(tokenA, tokenB);
      require(lp != address(0), 'no lp token');
      ensureApprove(tokenA, address(router));
      ensureApprove(tokenB, address(router));
      ensureApprove(lp, address(router));
      pairs[tokenA][tokenB] = lp;
      pairs[tokenB][tokenA] = lp;
    }
    return lp;
  }
// Solidity 0.6.12
/// @dev Compute optimal deposit amount
/// @param amtA amount of token A desired to deposit
/// @param amtB amount of token B desired to deposit
/// @param resA amount of token A in reserve
/// @param resB amount of token B in reserve
function optimalDeposit(
    uint amtA,
    uint amtB,
    uint resA,
    uint resB
  ) internal pure returns (uint swapAmt, bool isReversed) {
    if (amtA.mul(resB) >= amtB.mul(resA)) {
      swapAmt = _optimalDepositA(amtA, amtB, resA, resB);
      isReversed = false;
    } else {
      swapAmt = _optimalDepositA(amtB, amtA, resB, resA);
      isReversed = true;
    }
  }
// Solidity 0.6.12
/// @dev Compute optimal deposit amount helper.
/// @param amtA amount of token A desired to deposit
/// @param amtB amount of token B desired to deposit
/// @param resA amount of token A in reserve
/// @param resB amount of token B in reserve
/// Formula: https://blog.alphafinance.io/byot/
function _optimalDepositA(
    uint amtA,
    uint amtB,
    uint resA,
    uint resB
  ) internal pure returns (uint) {
    require(amtA.mul(resB) >= amtB.mul(resA), 'Reversed');
    uint a = 997;
    uint b = uint(1997).mul(resA);
    uint _c = (amtA.mul(resB)).sub(amtB.mul(resA));
    uint c = _c.mul(1000).div(amtB.add(resB)).mul(resA);
    uint d = a.mul(c).mul(4);
    uint e = HomoraMath.sqrt(b.mul(b).add(d));
    uint numerator = e.sub(b);
    uint denominator = a.mul(2);
    return numerator.div(denominator);
  }
// Solidity 0.6.12
/// @dev Add liquidity to Sushiswap pool, with no staking rewards (use WERC20 wrapper)
/// @param tokenA Token A for the pair
/// @param tokenB Token B for the pair
/// @param amt Amounts of tokens to supply, borrow, and get.
function addLiquidityWERC20(
    address tokenA,
    address tokenB,
    Amounts calldata amt
  ) external payable {
    address lp = getAndApprovePair(tokenA, tokenB);
    // 1-5. add liquidity
    addLiquidityInternal(tokenA, tokenB, amt, lp);

    // 6. Put collateral
    doPutCollateral(lp, IERC20(lp).balanceOf(address(this)));

    // 7. Refund leftovers to users
    doRefundETH();
    doRefund(tokenA);
    doRefund(tokenB);
  }
// Solidity 0.6.12
/// @dev Add liquidity to Sushiswap pool, with staking to masterChef
/// @param tokenA Token A for the pair
/// @param tokenB Token B for the pair
/// @param amt Amounts of tokens to supply, borrow, and get.
/// @param pid Pool id
function addLiquidityWMasterChef(
    address tokenA,
    address tokenB,
    Amounts calldata amt,
    uint pid
  ) external payable {
    address lp = getAndApprovePair(tokenA, tokenB);
    (address lpToken, , , ) = wmasterchef.chef().poolInfo(pid);
    require(lpToken == lp, 'incorrect lp token');

    // 1-5. add liquidity
    addLiquidityInternal(tokenA, tokenB, amt, lp);

    // 6. Take out collateral
    (, address collToken, uint collId, uint collSize) = bank.getCurrentPositionInfo();
    if (collSize > 0) {
      (uint decodedPid, ) = wmasterchef.decodeId(collId);
      require(pid == decodedPid, 'incorrect pid');
      require(collToken == address(wmasterchef), 'collateral token & wmasterchef mismatched');
      bank.takeCollateral(address(wmasterchef), collId, collSize);
      wmasterchef.burn(collId, collSize);
    }

    // 7. Put collateral
    ensureApprove(lp, address(wmasterchef));
    uint amount = IERC20(lp).balanceOf(address(this));
    uint id = wmasterchef.mint(pid, amount);
    bank.putCollateral(address(wmasterchef), id, amount);

    // 8. Refund leftovers to users
    doRefundETH();
    doRefund(tokenA);
    doRefund(tokenB);

    // 9. Refund sushi
    doRefund(sushi);
  }