lohoz/Smart-Contract-MultiTask-Dataset huggingface dataset:
// Solidity 0.4.18
// Calculate commission on prefunded and raised ether.
function calcCommission()
        internal
        view
        returns(uint)
    {
        uint commission = (this.balance + PRESALE_ETH_RAISE) / COMMISSION_DIV;
        // Edge case that prefund causes commission to be greater than balance
        return commission <= this.balance ? commission : this.balance;
    }
// Solidity 0.5.2
/// @notice Check whether an address is a regular address or not.
/// @param _addr Address of the contract that has to be checked
/// @return `true` if `_addr` is a regular address (not a contract)
function isRegularAddress(address _addr) internal view returns(bool) {
        if (_addr == address(0)) { return false; }
        uint size;
        assembly { size := extcodesize(_addr) } // solium-disable-line security/no-inline-assembly
        return size == 0;
    }
// Solidity 0.5.2
/// @notice Helper function actually performing the sending of tokens.
/// @param _operator The address performing the send
/// @param _from The address holding the tokens being sent
/// @param _to The address of the recipient
/// @param _amount The number of tokens to be sent
/// @param _data Data generated by the user to be passed to the recipient
/// @param _operatorData Data generated by the operator to be passed to the recipient
/// @param _preventLocking `true` if you want this function to throw when tokens are sent to a contract not
///  implementing `ERC777tokensRecipient`.
///  ERC777 native Send functions MUST set this parameter to `true`, and backwards compatible ERC20 transfer
///  functions SHOULD set this parameter to `false`.
function _send(
        address _operator,
        address _from,
        address _to,
        uint256 _amount,
        bytes memory _data,
        bytes memory _operatorData,
        bool _preventLocking
    )
        internal
    {
        callSender(_operator, _from, _to, _amount, _data, _operatorData);

        super._transfer(_from, _to, _amount); // TODO test it does not call this._transfer (which would emit 2 Sent event)

        callRecipient(_operator, _from, _to, _amount, _data, _operatorData, _preventLocking);

        emit Sent(_operator, _from, _to, _amount, _data, _operatorData);
    }
// Solidity 0.5.2
/// @notice Helper function that checks for ERC777TokensRecipient on the recipient and calls it.
///  May throw according to `_preventLocking`
/// @param _operator The address performing the send or mint
/// @param _from The address holding the tokens being sent
/// @param _to The address of the recipient
/// @param _amount The number of tokens to be sent
/// @param _data Data generated by the user to be passed to the recipient
/// @param _operatorData Data generated by the operator to be passed to the recipient
/// @param _preventLocking `true` if you want this function to throw when tokens are sent to a contract not
///  implementing `ERC777TokensRecipient`.
///  ERC777 native Send functions MUST set this parameter to `true`, and backwards compatible ERC20 transfer
///  functions SHOULD set this parameter to `false`.
function callRecipient(
        address _operator,
        address _from,
        address _to,
        uint256 _amount,
        bytes memory _data,
        bytes memory _operatorData,
        bool _preventLocking
    )
        internal
    {
        address recipientImplementation = interfaceAddr(_to, "ERC777TokensRecipient");
        if (recipientImplementation != address(0)) {
            ERC777TokensRecipient(recipientImplementation).tokensReceived(
                _operator, _from, _to, _amount, _data, _operatorData);
        } else if (_preventLocking) {
            require(isRegularAddress(_to), "Cannot send to contract without ERC777TokensRecipient");
        }
    }
// Solidity 0.5.16
/// @notice Get exchange dynamic fee related keys
/// @return threshold, weight decay, rounds, and max fee
function getExchangeDynamicFeeConfig() internal view returns (DynamicFeeConfig memory) {
        bytes32[] memory keys = new bytes32[](4);
        keys[0] = SETTING_EXCHANGE_DYNAMIC_FEE_THRESHOLD;
        keys[1] = SETTING_EXCHANGE_DYNAMIC_FEE_WEIGHT_DECAY;
        keys[2] = SETTING_EXCHANGE_DYNAMIC_FEE_ROUNDS;
        keys[3] = SETTING_EXCHANGE_MAX_DYNAMIC_FEE;
        uint[] memory values = flexibleStorage().getUIntValues(SETTING_CONTRACT_NAME, keys);
        return DynamicFeeConfig({threshold: values[0], weightDecay: values[1], rounds: values[2], maxFee: values[3]});
    }
// Solidity 0.5.16
// solhint-disable no-complex-fallback
function() external payable {
        // Mutable call setting Proxyable.messageSender as this is using call not delegatecall
        target.setMessageSender(msg.sender);

        assembly {
            let free_ptr := mload(0x40)
            calldatacopy(free_ptr, 0, calldatasize)

            /* We must explicitly forward ether to the underlying contract as well. */
            let result := call(gas, sload(target_slot), callvalue, free_ptr, calldatasize, 0, 0)
            returndatacopy(free_ptr, 0, returndatasize)

            if iszero(result) {
                revert(free_ptr, returndatasize)
            }
            return(free_ptr, returndatasize)
        }
    }
// Solidity 0.5.16
/**
 * SIP-139
 * resets the stored value for _lastExchangeRate for multiple currencies to the latest rate
 * can be used to un-suspend synths after a suspension happenned
 * doesn't check deviations here, so believes that owner knows better
 * emits LastRateOverriden
 */
function resetLastExchangeRate(bytes32[] calldata currencyKeys) external onlyOwner {
        (uint[] memory rates, bool anyRateInvalid) = _exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);

        require(!anyRateInvalid, "Rates for given synths not valid");

        for (uint i = 0; i < currencyKeys.length; i++) {
            emit LastRateOverriden(currencyKeys[i], _lastExchangeRate[currencyKeys[i]], rates[i]);
            _lastExchangeRate[currencyKeys[i]] = rates[i];
        }
    }
// Solidity 0.5.16
/**
 * Rate is invalid if:
 * - is outside of deviation bounds relative to previous non-zero rate
 * - (warm up case) if previous rate was 0 (init), gets last 4 rates from oracle, and checks
 * if rate is outside of deviation w.r.t any of the 3 previous ones (excluding the last one).
 */
function _isRateOutOfBounds(bytes32 currencyKey, uint currentRate) internal view returns (bool) {
        if (currentRate == 0) {
            return true;
        }

        uint lastRateFromExchange = _lastExchangeRate[currencyKey];

        if (lastRateFromExchange > 0) {
            return _isDeviationAboveThreshold(lastRateFromExchange, currentRate);
        }

        // if no last exchange for this synth, then we need to look up last 3 rates (+1 for current rate)
        (uint[] memory rates, ) = _exchangeRates().ratesAndUpdatedTimeForCurrencyLastNRounds(currencyKey, 4, 0);

        // start at index 1 to ignore current rate
        for (uint i = 1; i < rates.length; i++) {
            // ignore any empty rates in the past (otherwise we will never be able to get validity)
            if (rates[i] > 0 && _isDeviationAboveThreshold(rates[i], currentRate)) {
                return true;
            }
        }

        return false;
    }
// Solidity 0.8.4
/**
 * @notice Gets the strike price by multiplying the current underlying price
 * with a multiplier
 * @param expiryTimestamp is the unix timestamp of expiration
 * @param isPut is whether option is put or call
 * @return newStrikePrice is the strike price of the option (ex: for BTC might be 45000 * 10 ** 8)
 * @return newDelta will be set to zero for percent strike selection
 */
function getStrikePrice(uint256 expiryTimestamp, bool isPut)
        external
        view
        returns (uint256 newStrikePrice, uint256 newDelta)
    {
        require(
            expiryTimestamp > block.timestamp,
            "Expiry must be in the future!"
        );

        // asset price
        uint256 strikePrice =
            optionsPremiumPricer.getUnderlyingPrice().mul(strikeMultiplier).div(
                STRIKE_MULTIPLIER
            );

        newStrikePrice = isPut
            ? strikePrice.sub(strikePrice % step)
            : strikePrice.add(step.sub(strikePrice % step));

        newDelta = 0;
    }
// Solidity 0.5.2
// TODO could potentialy get ir fo this and use operatorSend instead (the token contract itself could be an defaultOperator)
function sendFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external {
        require(msg.sender == address(this), "only to be used by contract to support meta-tx"); // allow _from to allow gas estimatiom
        _send(_from, _from, _to, _amount, _data, "", true);
    }
// Solidity 0.4.24
/* Transfer the balance from the sender's address to the address _to */
function transfer(address _to, uint256 _value) public returns (bool success) {
        if (balances[msg.sender] >= _value
            && _value > 0
            && balances[_to] + _value > balances[_to]) {
			balances[msg.sender] = balances[msg.sender].sub(_value);
            balances[_to] = balances[_to].add(_value);
            Transfer(msg.sender, _to, _value);
            return true;
        } else {
            return false;
        }
    }
// Solidity 0.4.24
/* Withdraws to address _to form the address _from up to the amount _value */
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        if (balances[_from] >= _value
            && allowed[_from][msg.sender] >= _value
            && _value > 0
            && balances[_to] + _value > balances[_to]) {
            balances[_from] = balances[_from].sub(_value);
            allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
            balances[_to] = balances[_to].add(_value);
            Transfer(_from, _to, _value);
            return true;
        } else {
            return false;
        }
    }
// Solidity 0.7.6
// Only the liqMiningEmergencyHandler can call this function, when its in emergencyMode
// this will allow a spender to spend the whole balance of the specified tokens from this contract
// as well as to spend tokensForLpHolder from the respective lp holders for expiries specified
// the spender should ideally be a contract with logic for users to withdraw out their funds.
function setUpEmergencyMode(uint256[] calldata expiries, address spender) external override {
        (, bool emergencyMode) = pausingManager.checkLiqMiningStatus(address(this));
        require(emergencyMode, "NOT_EMERGENCY");

        (address liqMiningEmergencyHandler, , ) = pausingManager.liqMiningEmergencyHandler();
        require(msg.sender == liqMiningEmergencyHandler, "NOT_EMERGENCY_HANDLER");

        for (uint256 i = 0; i < expiries.length; i++) {
            IPendleLpHolder(expiryData[expiries[i]].lpHolder).setUpEmergencyMode(spender);
        }
        IERC20(pendleTokenAddress).approve(spender, type(uint256).max);
    }
// Solidity 0.7.6
/**
 * @notice fund new epochs
 * @dev Once the last epoch is over, the program is permanently override
 * @dev the settings must be set before epochs can be funded
 => if funded=true, means that epochs have been funded & have already has valid allocation settings
 * conditions:
 * Must only be called by governance
 */
function fund(uint256[] calldata _rewards) external override onlyGovernance {
        checkNotPaused();
        // Can only be fund if there is already a setting
        require(latestSetting.id > 0, "NO_ALLOC_SETTING");
        // Once the program is over, cannot fund
        require(_getCurrentEpochId() <= numberOfEpochs, "LAST_EPOCH_OVER");

        uint256 nNewEpochs = _rewards.length;
        uint256 totalFunded;
        // all the funding will be used for new epochs
        for (uint256 i = 0; i < nNewEpochs; i++) {
            totalFunded = totalFunded.add(_rewards[i]);
            epochData[numberOfEpochs + i + 1].totalRewards = _rewards[i];
        }

        require(totalFunded > 0, "ZERO_FUND");
        funded = true;
        numberOfEpochs = numberOfEpochs.add(nNewEpochs);
        IERC20(pendleTokenAddress).safeTransferFrom(msg.sender, address(this), totalFunded);
        emit Funded(_rewards, numberOfEpochs);
    }
// Solidity 0.7.6
/**
 @notice top up rewards for any funded future epochs (but not to create new epochs)
 * conditions:
 * Must only be called by governance
 * The contract must have been funded already
 */
function topUpRewards(uint256[] calldata _epochIds, uint256[] calldata _rewards)
        external
        override
        onlyGovernance
        isFunded
    {
        checkNotPaused();
        require(latestSetting.id > 0, "NO_ALLOC_SETTING");
        require(_epochIds.length == _rewards.length, "INVALID_ARRAYS");

        uint256 curEpoch = _getCurrentEpochId();
        uint256 endEpoch = numberOfEpochs;
        uint256 totalTopUp;

        for (uint256 i = 0; i < _epochIds.length; i++) {
            require(curEpoch < _epochIds[i] && _epochIds[i] <= endEpoch, "INVALID_EPOCH_ID");
            totalTopUp = totalTopUp.add(_rewards[i]);
            epochData[_epochIds[i]].totalRewards = epochData[_epochIds[i]].totalRewards.add(
                _rewards[i]
            );
        }

        require(totalTopUp > 0, "ZERO_FUND");
        IERC20(pendleTokenAddress).safeTransferFrom(msg.sender, address(this), totalTopUp);
        emit RewardsToppedUp(_epochIds, _rewards);
    }
// Solidity 0.7.6
/**
 @notice set a new allocation setting, which will be applied from the next epoch onwards
 @dev  all the epochData from latestSetting.firstEpochToApply+1 to current epoch will follow the previous
 allocation setting
 @dev We must set the very first allocation setting before the start of epoch 1,
 otherwise epoch 1 will not have any allocation setting!
 In that case, we will not be able to set any allocation and hence its not possible to
 fund the contract as well
 => We should just throw this contract away, and funds are SAFU!
 @dev the length of _expiries array is expected to be small, 2 or 3
 @dev it's intentional that we don't check the existence of expiries
 */
function setAllocationSetting(
        uint256[] calldata _expiries,
        uint256[] calldata _allocationNumerators
    ) external onlyGovernance {
        checkNotPaused();
        require(_expiries.length == _allocationNumerators.length, "INVALID_ALLOCATION");
        if (latestSetting.id == 0) {
            require(block.timestamp < startTime, "LATE_FIRST_ALLOCATION");
        }

        uint256 curEpoch = _getCurrentEpochId();
        // set the settingId for past epochs
        for (uint256 i = latestSetting.firstEpochToApply; i <= curEpoch; i++) {
            epochData[i].settingId = latestSetting.id;
        }

        // create a new setting that will be applied from the next epoch onwards
        latestSetting.firstEpochToApply = curEpoch + 1;
        latestSetting.id++;

        uint256 sumAllocationNumerators;
        for (uint256 _i = 0; _i < _expiries.length; _i++) {
            allocationSettings[latestSetting.id][_expiries[_i]] = _allocationNumerators[_i];
            sumAllocationNumerators = sumAllocationNumerators.add(_allocationNumerators[_i]);
        }
        require(sumAllocationNumerators == ALLOCATION_DENOMINATOR, "INVALID_ALLOCATION");
        emit AllocationSettingSet(_expiries, _allocationNumerators);
    }
// Solidity 0.7.6
/**
 * @notice Similar to stake() function, but using a permit to approve for LP tokens first
 */
function stakeWithPermit(
        uint256 expiry,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external
        override
        isFunded
        nonReentrant
        nonContractOrWhitelisted
        returns (address newLpHoldingContractAddress)
    {
        checkNotPaused();
        address xyt = address(data.xytTokens(forgeId, underlyingAsset, expiry));
        address marketAddress = data.getMarket(marketFactoryId, xyt, baseToken);
        // Pendle Market LP tokens are EIP-2612 compliant, hence we can approve liq-mining contract using a signature
        IPendleYieldToken(marketAddress).permit(
            msg.sender,
            address(this),
            amount,
            deadline,
            v,
            r,
            s
        );

        newLpHoldingContractAddress = _stake(expiry, amount);
    }
// Solidity 0.7.6
/**
 * @notice Use to withdraw their LP from a specific expiry
 Conditions:
 * only be called if the contract has been funded.
 * must have Reentrancy protection
 * only be called if 0 < current epoch (always can withdraw)
 */
function withdraw(uint256 expiry, uint256 amount) external override nonReentrant isFunded {
        checkNotPaused();
        uint256 curEpoch = _getCurrentEpochId();
        require(curEpoch > 0, "NOT_STARTED");
        require(amount != 0, "ZERO_AMOUNT");

        ExpiryData storage exd = expiryData[expiry];
        require(exd.balances[msg.sender] >= amount, "INSUFFICIENT_BALANCE");

        _pushLpToken(expiry, amount);
        emit Withdrawn(expiry, msg.sender, amount);
    }
// Solidity 0.7.6
/**
 * @notice use to claim PENDLE rewards
 Conditions:
 * only be called if the contract has been funded.
 * must have Reentrancy protection
 * only be called if 0 < current epoch (always can withdraw)
 * Anyone can call it (and claim it for any other user)
 */
function redeemRewards(uint256 expiry, address user)
        external
        override
        isFunded
        nonReentrant
        returns (uint256 rewards)
    {
        checkNotPaused();
        uint256 curEpoch = _getCurrentEpochId();
        require(curEpoch > 0, "NOT_STARTED");
        require(user != address(0), "ZERO_ADDRESS");
        require(userExpiries[user].hasExpiry[expiry], "INVALID_EXPIRY");

        rewards = _beforeTransferPendingRewards(expiry, user);
        if (rewards != 0) {
            IERC20(pendleTokenAddress).safeTransfer(user, rewards);
        }
    }
// Solidity 0.7.6
/**
 @notice update the following stake data for the current epoch:
 - epochData[_curEpoch].stakeUnitsForExpiry
 - epochData[_curEpoch].lastUpdatedForExpiry
 @dev If this is the very first transaction involving this expiry, then need to update for the
 previous epoch as well. If the previous didn't have any transactions at all, (and hence was not
 updated at all), we need to update it and check the previous previous ones, and so on..
 @dev must be called right before every _updatePendingRewards()
 @dev this is the only function that updates lastTimeUserStakeUpdated & stakeUnitsForExpiry
 @dev other functions must make sure that totalStakeLPForExpiry could be assumed
 to stay exactly the same since lastTimeUserStakeUpdated until now;
 @dev to be called only by _updatePendingRewards
 */
function _updateStakeDataForExpiry(uint256 expiry) internal {
        uint256 _curEpoch = _getCurrentEpochId();

        // loop through all epochData in descending order
        for (uint256 i = Math.min(_curEpoch, numberOfEpochs); i > 0; i--) {
            uint256 epochEndTime = _endTimeOfEpoch(i);
            uint256 lastUpdatedForEpoch = epochData[i].lastUpdatedForExpiry[expiry];

            if (lastUpdatedForEpoch == epochEndTime) {
                break; // its already updated until this epoch, our job here is done
            }

            // if the epoch hasn't been fully updated yet, we will update it
            // just add the amount of units contributed by users since lastUpdatedForEpoch -> now
            // by calling _calcUnitsStakeInEpoch
            epochData[i].stakeUnitsForExpiry[expiry] = epochData[i].stakeUnitsForExpiry[expiry]
                .add(
                _calcUnitsStakeInEpoch(expiryData[expiry].totalStakeLP, lastUpdatedForEpoch, i)
            );
            // If the epoch has ended, lastUpdated = epochEndTime
            // If not yet, lastUpdated = block.timestamp (aka now)
            epochData[i].lastUpdatedForExpiry[expiry] = Math.min(block.timestamp, epochEndTime);
        }
    }
// Solidity 0.7.6
// calc the amount of rewards the user is eligible to receive from this epoch
// but we will return the amount per vestingEpoch instead
function _calcAmountRewardsForUserInEpoch(
        uint256 expiry,
        address user,
        uint256 epochId
    ) internal view returns (uint256 rewardsPerVestingEpoch) {
        uint256 settingId =
            epochId >= latestSetting.firstEpochToApply
                ? latestSetting.id
                : epochData[epochId].settingId;

        uint256 rewardsForThisExpiry =
            epochData[epochId].totalRewards.mul(allocationSettings[settingId][expiry]).div(
                ALLOCATION_DENOMINATOR
            );

        rewardsPerVestingEpoch = rewardsForThisExpiry
            .mul(epochData[epochId].stakeUnitsForUser[user][expiry])
            .div(epochData[epochId].stakeUnitsForExpiry[expiry])
            .div(vestingEpochs);
    }
// Solidity 0.7.6
/**
 * @notice returns the stakeUnits in the _epochId(th) epoch of an user if he stake from _startTime to now
 * @dev to calculate durationStakeThisEpoch:
 *   user will stake from _startTime -> _endTime, while the epoch last from _startTimeOfEpoch -> _endTimeOfEpoch
 *   => the stakeDuration of user will be min(_endTime,_endTimeOfEpoch) - max(_startTime,_startTimeOfEpoch)
 */
function _calcUnitsStakeInEpoch(
        uint256 lpAmount,
        uint256 _startTime,
        uint256 _epochId
    ) internal view returns (uint256 stakeUnitsForUser) {
        uint256 _endTime = block.timestamp;

        uint256 _l = Math.max(_startTime, _startTimeOfEpoch(_epochId));
        uint256 _r = Math.min(_endTime, _endTimeOfEpoch(_epochId));
        uint256 durationStakeThisEpoch = _r.subMax0(_l);

        return lpAmount.mul(durationStakeThisEpoch);
    }
// Solidity 0.7.6
/**
 @notice Calc the amount of rewards that the user can receive now.
 @dev To be called before any rewards is transferred out
 */
function _beforeTransferPendingRewards(uint256 expiry, address user)
        internal
        returns (uint256 amountOut)
    {
        _updatePendingRewards(expiry, user);

        uint256 _lastEpoch = Math.min(_getCurrentEpochId(), numberOfEpochs + vestingEpochs);
        for (uint256 i = expiryData[expiry].lastEpochClaimed[user]; i <= _lastEpoch; i++) {
            if (epochData[i].availableRewardsForUser[user] > 0) {
                amountOut = amountOut.add(epochData[i].availableRewardsForUser[user]);
                epochData[i].availableRewardsForUser[user] = 0;
            }
        }

        expiryData[expiry].lastEpochClaimed[user] = _lastEpoch;
        emit PendleRewardsSettled(expiry, user, amountOut);
        return amountOut;
    }
// Solidity 0.7.6
/**
 * @dev all LP interests related functions are almost identical to markets' functions
 * Very similar to the function in PendleMarketBase. Any major differences are likely to be bugs
 Please refer to it for more details
 */
function _updateParamL(uint256 expiry) internal {
        ExpiryData storage exd = expiryData[expiry];

        if (!checkNeedUpdateParamL(expiry)) return;

        IPendleLpHolder(exd.lpHolder).redeemLpInterests();

        uint256 currentNYield = IERC20(underlyingYieldToken).balanceOf(exd.lpHolder);
        (uint256 firstTerm, uint256 paramR) = _getFirstTermAndParamR(expiry, currentNYield);

        uint256 secondTerm;

        if (exd.totalStakeLP != 0) secondTerm = paramR.mul(MULTIPLIER).div(exd.totalStakeLP);

        // Update new states
        exd.paramL = firstTerm.add(secondTerm);
        exd.lastNYield = currentNYield;
    }