lohoz/Smart-Contract-MultiTask-Dataset huggingface dataset:
// Solidity 0.8.7
/**
 * @dev Manual minting by owner, callable by owner; phase can be one of [1,2,3,4]
 */
function mintOwner(address[] calldata owners, uint256[] calldata counts, uint256 phase) external onlyOwner {
        require(owners.length == counts.length, "Bad length");
         
        for (uint256 i = 0; i < counts.length; i++) {
            require(reserveForPhase[phase] >= counts[i], "Reserve exceeded");
            
            mintInternal(owners[i], counts[i], phase);
            reserveForPhase[phase] -= counts[i];
            supplyForPhase[phase] -= counts[i];
        }
    }
// Solidity 0.8.7
/**
 * @dev Gets the price tier from token count
 */
function getPrice(uint256 count) public view returns (uint256) {
        if (count <= 2) {
            return price12;
        } else if (count <= 4) {
            return price34;
        } else {
            return price56;
        }
    }
// Solidity 0.8.7
/**
 * @dev Public minting during public sale or presale
 */
function mint(uint256 count) public payable{
        require(!mintPaused, "Minting is currently paused");
        require(currentPhase > 0, "Sale not started");
        require(publicSaleEnded == false, "Sale ended");

        require(msg.value == count * getPrice(count), "Ether value incorrect");
        require(supplyForPhase[currentPhase] - reserveForPhase[currentPhase] >= count, "Supply exceeded");
        
        if (presaleEnded) {
            // public sale checks
            require(count <= maxPerTxDuringSale, "Too many tokens");
        } else {
            // presale checks
            require(isWhitelisted[msg.sender], "You are not whitelisted");
            require(mintedDuringPresaleAtPhase[currentPhase][msg.sender] + count <= maxPerWalletDuringPresale, "Count exceeded during presale");
            mintedDuringPresaleAtPhase[currentPhase][msg.sender] += count;
        }
        
        supplyForPhase[currentPhase] -= count;
        mintInternal(msg.sender, count, currentPhase);
    }
// Solidity 0.5.11
/**
 * @dev The function which performs the multi path swap.
 * @param fromToken Address of the source token
 * @param toToken Address of the destination token
 * @param fromAmount Amount of source tokens to be swapped
 * @param toAmount Minimum destination token amount expected out of this swap
 * @param expectedAmount Expected amount of destination tokens without slippage
 * @param path Route to be taken for this swap to take place
 * @param mintPrice Price of gas at the time of minting of gas tokens, if any. In wei. 0 means gas token will not be used
 * @param beneficiary Beneficiary address
 * @param donationPercentage Percentage of returned amount to be transferred to beneficiary, if beneficiary is available. If this is passed as
 * 0 then 100% will be transferred to beneficiary. Pass 10000 for 100%
 * @param referrer referral id
 */
function multiSwap(
        IERC20 fromToken,
        IERC20 toToken,
        uint256 fromAmount,
        uint256 toAmount,
        uint256 expectedAmount,
        Utils.Path[] memory path,
        uint256 mintPrice,
        address payable beneficiary,
        uint256 donationPercentage,
        string memory referrer
    )
        public
        payable
        whenNotPaused
        returns (uint256)
    {
        //Referral id can never be empty
        require(bytes(referrer).length > 0, "Invalid referrer");

        require(donationPercentage <= 10000, "Invalid value");

        require(toAmount > 0, "To amount can not be 0");

        uint256 receivedAmount = performSwap(
            fromToken,
            toToken,
            fromAmount,
            toAmount,
            path,
            mintPrice
        );

        takeFeeAndTransferTokens(
            toToken,
            toAmount,
            receivedAmount,
            beneficiary,
            donationPercentage,
            referrer
        );

        //If any ether is left at this point then we transfer it back to the user
        uint256 remEthBalance = Utils.tokenBalance(
            Utils.ethAddress(),
            address(this)
        );
        if ( remEthBalance > 0) {
            msg.sender.transfer(remEthBalance);
        }

        //Contract should not have any remaining balance after entire execution
        require(
            Utils.tokenBalance(address(toToken), address(this)) == 0,
            "Destination tokens are stuck"
        );

        emit Swapped(
            msg.sender,
            beneficiary == address(0)?msg.sender:beneficiary,
            address(fromToken),
            address(toToken),
            fromAmount,
            receivedAmount,
            expectedAmount,
            referrer
        );

        return receivedAmount;
    }
// Solidity 0.6.6
/**
 * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
 */
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }
// Solidity 0.6.11
// Returns the value of excess collateral held in this Pusd pool, compared to what is needed to maintain the global collateral ratio
function availableExcessCollatDV() public view returns (uint256) {
        uint256 total_supply = PUSD.totalSupply();
        uint256 global_collateral_ratio = PUSD.global_collateral_ratio();
        uint256 global_collat_value = PUSD.globalCollateralValue();

        if (global_collateral_ratio > COLLATERAL_RATIO_PRECISION) global_collateral_ratio = COLLATERAL_RATIO_PRECISION; // Handles an overcollateralized contract with CR > 1
        uint256 required_collat_dollar_value_d18 = (total_supply.mul(global_collateral_ratio)).div(COLLATERAL_RATIO_PRECISION); // Calculates collateral needed to back each 1 PUSD with $1 of collateral at current collat ratio
        if (global_collat_value > required_collat_dollar_value_d18) return global_collat_value.sub(required_collat_dollar_value_d18);
        else return 0;
    }
// Solidity 0.6.11
// We separate out the 1t1, fractional and algorithmic minting functions for gas efficiency 
function mint1t1PUSD(uint256 collateral_amount, uint256 PUSD_out_min) external notMintPaused {
        uint256 collateral_amount_d18 = collateral_amount * (10 ** missing_decimals);
        uint256 global_collateral_ratio = PUSD.global_collateral_ratio();

        require(global_collateral_ratio >= COLLATERAL_RATIO_MAX, "Collateral ratio must be >= 1");
        require((collateral_token.balanceOf(address(this))).sub(unclaimedPoolCollateral).add(collateral_amount) <= pool_ceiling, "[Pool's Closed]: Ceiling reached");
        
        (uint256 pusd_amount_d18) = PusdPoolLibrary.calcMint1t1PUSD(
            getCollateralPrice(),
            0,
            collateral_amount_d18
        ); //1 PUSD for each $1 worth of collateral

        require(PUSD_out_min <= pusd_amount_d18, "Slippage limit reached");
        collateral_token.transferFrom(msg.sender, address(this), collateral_amount);
        uint256 total_feeAmount = pusd_amount_d18.mul(minting_fee).div(1e6);
        PUSD.pool_mint(bonus_address, total_feeAmount.mul(70).div(100));
        PUSD.pool_mint(msg.sender, pusd_amount_d18.sub(total_feeAmount));
    }
// Solidity 0.6.11
// 0% collateral-backed
// function mintAlgorithmicPUSD(uint256 pegs_amount_d18, uint256 PUSD_out_min) external notMintPaused {
//     uint256 pegs_price = PUSD.pegs_price();
//     uint256 global_collateral_ratio = PUSD.global_collateral_ratio();
//     require(global_collateral_ratio == 0, "Collateral ratio must be 0");
//     (uint256 pusd_amount_d18) = PusdPoolLibrary.calcMintAlgorithmicPUSD(
//         minting_fee, 
//         pegs_price, // X PEGS / 1 USD
//         pegs_amount_d18
//     );
//     require(PUSD_out_min <= pusd_amount_d18, "Slippage limit reached");
//     PEGS.pool_burn_from(msg.sender, pegs_amount_d18);
//     PUSD.pool_mint(msg.sender, pusd_amount_d18);
// }
// Will fail if fully collateralized or fully algorithmic
// > 0% and < 100% collateral-backed
function mintFractionalPUSD(uint256 collateral_amount, uint256 pegs_amount, uint256 PUSD_out_min) external notMintPaused {
        uint256 pusd_price = PUSD.pusd_price();
        uint256 pegs_price = PUSD.pegs_price();
        uint256 global_collateral_ratio = PUSD.global_collateral_ratio();

        require(global_collateral_ratio < COLLATERAL_RATIO_MAX && global_collateral_ratio > 0, "Collateral ratio needs to be between .000001 and .999999");
        require(collateral_token.balanceOf(address(this)).sub(unclaimedPoolCollateral).add(collateral_amount) <= pool_ceiling, "Pool ceiling reached, no more PUSD can be minted with this collateral");

        uint256 collateral_amount_d18 = collateral_amount * (10 ** missing_decimals);
        PusdPoolLibrary.MintFF_Params memory input_params = PusdPoolLibrary.MintFF_Params(
            0, 
            pegs_price,
            pusd_price,
            getCollateralPrice(),
            pegs_amount,
            collateral_amount_d18,
            (collateral_token.balanceOf(address(this)).sub(unclaimedPoolCollateral)),
            pool_ceiling,
            global_collateral_ratio
        );

        (uint256 mint_amount, uint256 pegs_needed) = PusdPoolLibrary.calcMintFractionalPUSD(input_params);

        require(PUSD_out_min <= mint_amount, "Slippage limit reached");
        require(pegs_needed <= pegs_amount, "Not enough PEGS inputted");
        PEGS.pool_burn_from(msg.sender, pegs_needed);
        collateral_token.transferFrom(msg.sender, address(this), collateral_amount);
        
        uint256 total_feeAmount = mint_amount.mul(minting_fee).div(1e6);
        PUSD.pool_mint(bonus_address, total_feeAmount.mul(70).div(100));
        PUSD.pool_mint(msg.sender, mint_amount.sub(total_feeAmount));
    }
// Solidity 0.6.11
// Redeem collateral. 100% collateral-backed
function redeem1t1PUSD(uint256 PUSD_amount, uint256 COLLATERAL_out_min) external notRedeemPaused {
        uint256 global_collateral_ratio = PUSD.global_collateral_ratio();
        require(global_collateral_ratio == COLLATERAL_RATIO_MAX, "Collateral ratio must be == 1");

        // // Need to adjust for decimals of collateral
        uint256 PUSD_amount_precision = PUSD_amount.div(10 ** missing_decimals);
        (uint256 collateral_needed) = PusdPoolLibrary.calcRedeem1t1PUSD(
            getCollateralPrice(),
            PUSD_amount_precision,
            0
        );

        require(collateral_needed <= collateral_token.balanceOf(address(this)), "Not enough collateral in pool");

    
        uint256 total_feeAmount = collateral_needed.mul(redemption_fee).div(1e6);
        
        redeemCollateralBalances[msg.sender] = redeemCollateralBalances[msg.sender].add(collateral_needed.sub(total_feeAmount));
        unclaimedPoolCollateral = unclaimedPoolCollateral.add(collateral_needed.sub(total_feeAmount));
        lastRedeemed[msg.sender] = block.number;

        require(COLLATERAL_out_min <= collateral_needed, "Slippage limit reached");
        
       
        // Move all external functions to the end
        uint256 transfer_amount = PUSD_amount.mul(redemption_fee).div(1e6).mul(70).div(100);
        PUSD.transferFrom(msg.sender, bonus_address, transfer_amount);
        PUSD.pool_burn_from(msg.sender, PUSD_amount.sub(transfer_amount));
    }
// Solidity 0.6.11
// Will fail if fully collateralized or algorithmic
// Redeem PUSD for collateral and PEGS. > 0% and < 100% collateral-backed
function redeemFractionalPUSD(uint256 PUSD_amount, uint256 PEGS_out_min, uint256 COLLATERAL_out_min) external notRedeemPaused {
        uint256 global_collateral_ratio = PUSD.global_collateral_ratio();

        require(global_collateral_ratio < COLLATERAL_RATIO_MAX && global_collateral_ratio > 0, "Collateral ratio needs to be between .000001 and .999999");

        uint256 PUSD_amount_post_fee = PUSD_amount.sub((PUSD_amount.mul(0)).div(PRICE_PRECISION));
        uint256 pegs_amount = PUSD_amount_post_fee.sub(PUSD_amount_post_fee.mul(global_collateral_ratio).div(PRICE_PRECISION)).mul(PRICE_PRECISION).div(PUSD.pegs_price());

        uint256 collateral_amount = PUSD_amount_post_fee.div(10 ** missing_decimals).mul(global_collateral_ratio).div(PRICE_PRECISION).mul(PRICE_PRECISION).div(getCollateralPrice());
        
        redeemCollateralBalances[msg.sender] = redeemCollateralBalances[msg.sender].add(collateral_amount.sub(collateral_amount.mul(redemption_fee).div(1e6)));
        unclaimedPoolCollateral = unclaimedPoolCollateral.add(collateral_amount.sub(collateral_amount.mul(redemption_fee).div(1e6)));

        redeemPEGSBalances[msg.sender] = redeemPEGSBalances[msg.sender].add(pegs_amount.sub(pegs_amount.mul(redemption_fee).div(1e6)));
        unclaimedPoolPEGS = unclaimedPoolPEGS.add(pegs_amount.sub(pegs_amount.mul(redemption_fee).div(1e6)));

        lastRedeemed[msg.sender] = block.number;

        require(collateral_amount <= collateral_token.balanceOf(address(this)).sub(unclaimedPoolCollateral), "Not enough collateral in pool");
        require(COLLATERAL_out_min <= collateral_amount && PEGS_out_min <= pegs_amount, "Slippage limit reached");
        
        // Move all external functions to the end
        uint256 transfer_amount = PUSD_amount.mul(redemption_fee).div(1e6).mul(70).div(100);
        PUSD.transferFrom(msg.sender, bonus_address, transfer_amount);
        PUSD.pool_burn_from(msg.sender, PUSD_amount.sub(transfer_amount));
        PEGS.pool_mint(address(this), pegs_amount.sub(pegs_amount.mul(redemption_fee).div(1e6)));
    }
// Solidity 0.6.11
// Redeem PUSD for PEGS. 0% collateral-backed
// function redeemAlgorithmicPUSD(uint256 PUSD_amount, uint256 PEGS_out_min) external notRedeemPaused {
//     uint256 pegs_price = PUSD.pegs_price();
//     uint256 global_collateral_ratio = PUSD.global_collateral_ratio();
//     require(global_collateral_ratio == 0, "Collateral ratio must be 0"); 
//     uint256 pegs_dollar_value_d18 = PUSD_amount;
//     pegs_dollar_value_d18 = pegs_dollar_value_d18.sub((pegs_dollar_value_d18.mul(redemption_fee)).div(PRICE_PRECISION)); //apply redemption fee
//     uint256 pegs_amount = pegs_dollar_value_d18.mul(PRICE_PRECISION).div(pegs_price);
//     redeemPEGSBalances[msg.sender] = redeemPEGSBalances[msg.sender].add(pegs_amount);
//     unclaimedPoolPEGS = unclaimedPoolPEGS.add(pegs_amount);
//     lastRedeemed[msg.sender] = block.number;
//     require(PEGS_out_min <= pegs_amount, "Slippage limit reached");
//     // Move all external functions to the end
//     PUSD.pool_burn_from(msg.sender, PUSD_amount);
//     PEGS.pool_mint(address(this), pegs_amount);
// }
// After a redemption happens, transfer the newly minted PEGS and owed collateral from this pool
// contract to the user. Redemption is split into two functions to prevent flash loans from being able
// to take out PUSD/collateral from the system, use an AMM to trade the new price, and then mint back into the system.
function collectRedemption() external {
        require((lastRedeemed[msg.sender].add(redemption_delay)) <= block.number, "Must wait for redemption_delay blocks before collecting redemption");
        bool sendPEGS = false;
        bool sendCollateral = false;
        uint PEGSAmount;
        uint CollateralAmount;

        // Use Checks-Effects-Interactions pattern
        if(redeemPEGSBalances[msg.sender] > 0){
            PEGSAmount = redeemPEGSBalances[msg.sender];
            redeemPEGSBalances[msg.sender] = 0;
            unclaimedPoolPEGS = unclaimedPoolPEGS.sub(PEGSAmount);

            sendPEGS = true;
        }
        
        if(redeemCollateralBalances[msg.sender] > 0){
            CollateralAmount = redeemCollateralBalances[msg.sender];
            redeemCollateralBalances[msg.sender] = 0;
            unclaimedPoolCollateral = unclaimedPoolCollateral.sub(CollateralAmount);

            sendCollateral = true;
        }

        if(sendPEGS == true){
            PEGS.transfer(msg.sender, PEGSAmount);
        }
        if(sendCollateral == true){
            collateral_token.transfer(msg.sender, CollateralAmount);
        }
    }
// Solidity 0.6.11
// When the protocol is recollateralizing, we need to give a discount of PEGS to hit the new CR target
// Thus, if the target collateral ratio is higher than the actual value of collateral, minters get PEGS for adding collateral
// This function simply rewards anyone that sends collateral to a pool with the same amount of PEGS + the bonus rate
// Anyone can call this function to recollateralize the protocol and take the extra PEGS value from the bonus rate as an arb opportunity
function recollateralizePUSD(uint256 collateral_amount, uint256 PEGS_out_min) external {
        require(recollateralizePaused == false, "Recollateralize is paused");
        uint256 collateral_amount_d18 = collateral_amount * (10 ** missing_decimals);
        uint256 pegs_price = PUSD.pegs_price();
        uint256 pusd_total_supply = PUSD.totalSupply();
        uint256 global_collateral_ratio = PUSD.global_collateral_ratio();
        uint256 global_collat_value = PUSD.globalCollateralValue();
        
        (uint256 collateral_units, uint256 amount_to_recollat) = PusdPoolLibrary.calcRecollateralizePUSDInner(
            collateral_amount_d18,
            getCollateralPrice(),
            global_collat_value,
            pusd_total_supply,
            global_collateral_ratio
        ); 

        uint256 collateral_units_precision = collateral_units.div(10 ** missing_decimals);

        uint256 pegs_paid_back = amount_to_recollat.mul(uint(1e6).add(bonus_rate)).div(pegs_price);

        require(PEGS_out_min <= pegs_paid_back, "Slippage limit reached");
        collateral_token.transferFrom(msg.sender, address(this), collateral_units_precision);
        PEGS.pool_mint(msg.sender, pegs_paid_back);
        
    }
// Solidity 0.6.11
// Function can be called by an PEGS holder to have the protocol buy back PEGS with excess collateral value from a desired collateral pool
// This can also happen if the collateral ratio > 1
function buyBackPEGS(uint256 PEGS_amount, uint256 COLLATERAL_out_min) external {
        require(buyBackPaused == false, "Buyback is paused");
        uint256 pegs_price = PUSD.pegs_price();
        
        PusdPoolLibrary.BuybackPEGS_Params memory input_params = PusdPoolLibrary.BuybackPEGS_Params(
            availableExcessCollatDV(),
            pegs_price,
            getCollateralPrice(),
            PEGS_amount
        );

        (uint256 collateral_equivalent_d18) = PusdPoolLibrary.calcBuyBackPEGS(input_params);
        uint256 collateral_precision = collateral_equivalent_d18.div(10 ** missing_decimals);

        require(COLLATERAL_out_min <= collateral_precision, "Slippage limit reached");
        // Give the sender their desired collateral and burn the PEGS
        PEGS.pool_burn_from(msg.sender, PEGS_amount);
        collateral_token.transfer(msg.sender, collateral_precision);
    }
// Solidity 0.6.11
// Combined into one function due to 24KiB contract memory limit
function setPoolParameters(uint256 new_ceiling, uint256 new_bonus_rate, uint256 new_redemption_delay, address _bonus_address) external onlyByOwnerOrGovernance {
        pool_ceiling = new_ceiling;
        bonus_rate = new_bonus_rate;
        redemption_delay = new_redemption_delay;
        minting_fee = PUSD.minting_fee();
        redemption_fee = PUSD.redemption_fee();
        bonus_address = _bonus_address;
    }
// Solidity 0.4.24
//=====================
// Main gameplay
//=====================
function playWar(uint sideBetPercent) public whenNotPaused TokenCheck payable {

      require(sideBetPercent >= 0 && sideBetPercent <= sideBetPercent_MAX);

      require(hasHandInProgress[msg.sender]==false);

      require(msg.value <= bet_MAX && msg.value >= bet_MIN);

      uint betAmount = msg.value;
      uint sideBetAmount = betAmount.mul(sideBetPercent).div(100);
      uint mainBetAmount = betAmount.sub(sideBetAmount);

      emit DEBUG_betSplit(mainBetAmount, sideBetAmount, sideBetPercent);

      //Initiate oraclize call
      bytes32 orcID = oraclize_query("WolframAlpha", "RandomSample[Range[416],2]",gasForShuffle);
      emit currentOrcID(orcID);

      uint orcFees = oraclize_getPrice("WolframAlpha", gasForShuffle);

      //check if previous hand was a tie and player chose to go to WAR
      if(firstHandInfo[msg.sender].isTied){
        assert(msg.value == firstHandInfo[msg.sender].mainBetAmount);
        assert(sideBetAmount == 0);
      }
      else{
        FirstHand memory thisHand = FirstHand({
          isTied : false,
          fees: orcFees,
          mainBetAmount : mainBetAmount
        });
        firstHandInfo[msg.sender] = thisHand;
      }

      Info memory info = Info({
          playerAddress : msg.sender,
          mainBetAmount : mainBetAmount,
          sideBetAmount : sideBetAmount,
          fees: orcFees,
          sideBetPercentage : sideBetPercent,
          playerHand : 0,
          houseHand : 0
      });

      hand_info[orcID] = info;
      refundPool[msg.sender] = msg.value.sub(orcFees);
      hasHandInProgress[msg.sender] = true;
    }
// Solidity 0.4.24
//=====================
// Special
//=====================
function getCardValue(uint card) private pure returns(uint){
      if (card > 416 || card < 1) {
        return 0;
      }

      card = card % 52;

      if (card == 0) {
        return 13;
      } else if (card <= 4) {
        return 14;
      } else if (card % 4 > 0) {
        card = card.div(4).add(1);
      } else {
        card = card.div(4);
      }

      return card == 1 ? 14 : card;
    }
// Solidity 0.4.21
// @dev function to decreaseApproval to spender
function decreaseApproval (address _spender, uint256 _subtractedValue) public returns (bool success) {
    uint256 oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = safeSub(oldValue,_subtractedValue);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }
// Solidity 0.8.4
// msg.sender must be the user who originally created the swap.
// Otherwise, the unique identifier will not match from the originally
// sending txn.
//
// NOTE: We're aware this function can be spoofed by creating a sha256 hash of msg.sender's address
// and _origTimestamp, but it's important to note refundTokensFromSource and sendTokensToDestination
// can only be executed by the owner/oracle. Therefore validation should be done by the oracle before
// executing those and the only possibility of a vulnerability is if someone has compromised the oracle account.
function fundSendToDestinationGas(
        bytes32 _id,
        uint256 _origTimestamp,
        uint256 _amount
    ) external payable {
        require(
            msg.value >= minimumGasForOperation,
            "you must send enough gas to cover the send transaction"
        );
        require(
            _id ==
                sha256(abi.encodePacked(msg.sender, _origTimestamp, _amount)),
            "we don't recognize this swap"
        );
        payable(oracleAddress).transfer(msg.value);


        //check if swap already exists
        if (!(swaps[_id].amount > 0 && swaps[_id].origTimestamp > 0)) {
            swaps[_id] = Swap({
                id: _id,
                origTimestamp: _origTimestamp,
                currentTimestamp: block.timestamp,
                isOutbound: true,
                isComplete: false,
                isRefunded: false,
                isSendGasFunded: true,
                swapAddress: msg.sender,
                amount: _amount
            });
        }

        emit destinationGasFunded(_id);
    }