lohoz/Smart-Contract-MultiTask-Dataset huggingface dataset:
// Solidity 0.6.12
/**
 	* @dev Get information for a handler
 	* @param handlerID Handler ID
 	* @return (success or failure, handler address, handler name)
 	*/
function getTokenHandlerInfo(uint256 handlerID) external view returns (bool, address, string memory)
	{
		bool support;
		address tokenHandlerAddr;
		string memory tokenName;
		if (dataStorageInstance.getTokenHandlerSupport(handlerID))
		{
			tokenHandlerAddr = dataStorageInstance.getTokenHandlerAddr(handlerID);
			IProxy TokenHandler = IProxy(tokenHandlerAddr);
			bytes memory data;
			(, data) = TokenHandler.handlerViewProxy(
				abi.encodeWithSelector(
					IMarketHandler
					.getTokenName.selector
				)
			);
			tokenName = abi.decode(data, (string));
			support = true;
		}

		return (support, tokenHandlerAddr, tokenName);
	}
// Solidity 0.6.12
/**
 	* @dev Register a handler
 	* @param handlerID Handler ID and address
 	* @param tokenHandlerAddr The handler address
 	* @return result the setter call in contextSetter contract
 	*/
function handlerRegister(uint256 handlerID, address tokenHandlerAddr, uint256 flashFeeRate, uint256 discountBase) onlyOwner external returns (bool result) {
		bytes memory callData = abi.encodeWithSelector(
					IManagerSlotSetter
					.handlerRegister.selector,
					handlerID, tokenHandlerAddr, flashFeeRate, discountBase
				);

			(result, ) = slotSetterAddr.delegatecall(callData);
		assert(result);
	}
// Solidity 0.6.12
/**
 	* @dev Update the (SI) rewards for a user
 	* @param userAddr The address of the user
 	* @param callerID The handler ID
 	* @return true (TODO: validate results)
 	*/
function rewardUpdateOfInAction(address payable userAddr, uint256 callerID) external returns (bool)
	{
		ContractInfo memory handlerInfo;
		(handlerInfo.support, handlerInfo.addr) = dataStorageInstance.getTokenHandlerInfo(callerID);
		if (handlerInfo.support)
		{
			IProxy TokenHandler;
			TokenHandler = IProxy(handlerInfo.addr);
			TokenHandler.siProxy(
				abi.encodeWithSelector(
					IServiceIncentive
					.updateRewardLane.selector,
					userAddr
				)
			);
		}

		return true;
	}
// Solidity 0.6.12
/**
 	* @dev Update interest of a user for a handler (internal)
 	* @param userAddr The user address
 	* @param callerID The handler ID
 	* @param allFlag Flag for the full calculation mode (calculting for all handlers)
 	* @return (uint256, uint256, uint256, uint256, uint256, uint256)
 	*/
function applyInterestHandlers(address payable userAddr, uint256 callerID, bool allFlag) external returns (uint256, uint256, uint256, uint256, uint256, uint256) {
    bytes memory callData = abi.encodeWithSelector(
				IHandlerManager
				.applyInterestHandlers.selector,
				userAddr, callerID, allFlag
			);

		(bool result, bytes memory returnData) = handlerManagerAddr.delegatecall(callData);
    assert(result);

    return abi.decode(returnData, (uint256, uint256, uint256, uint256, uint256, uint256));
  }
// Solidity 0.6.12
/**
 	* @dev Claim handler rewards for the user
 	* @param handlerID The ID of claim reward handler
 	* @param userAddr The user address
 	* @return true (TODO: validate results)
 	*/
function claimHandlerReward(uint256 handlerID, address payable userAddr) external returns (uint256) {
		bytes memory callData = abi.encodeWithSelector(
				IHandlerManager
				.claimHandlerReward.selector,
        handlerID, userAddr
			);

		(bool result, bytes memory returnData) = handlerManagerAddr.delegatecall(callData);
    assert(result);

    return abi.decode(returnData, (uint256));
	}
// Solidity 0.6.12
/**
 	* @dev Get the borrow and margin call limits of the user for all handlers
 	* @param userAddr The address of the user
 	* @return userTotalBorrowLimitAsset the sum of borrow limit for all handlers
 	* @return userTotalMarginCallLimitAsset the sume of margin call limit for handlers
 	*/
function getUserLimitIntraAsset(address payable userAddr) external view returns (uint256, uint256)
	{
		uint256 userTotalBorrowLimitAsset;
		uint256 userTotalMarginCallLimitAsset;

		for (uint256 handlerID; handlerID < tokenHandlerLength; handlerID++)
		{
			if (dataStorageInstance.getTokenHandlerSupport(handlerID))
			{
				uint256 depositHandlerAsset;
				uint256 borrowHandlerAsset;
				(depositHandlerAsset, borrowHandlerAsset) = _getUserIntraHandlerAssetWithInterest(userAddr, handlerID);
				uint256 borrowLimit = _getTokenHandlerBorrowLimit(handlerID);
				uint256 marginCallLimit = _getTokenHandlerMarginCallLimit(handlerID);
				uint256 userBorrowLimitAsset = depositHandlerAsset.unifiedMul(borrowLimit);
				uint256 userMarginCallLimitAsset = depositHandlerAsset.unifiedMul(marginCallLimit);
				userTotalBorrowLimitAsset = userTotalBorrowLimitAsset.add(userBorrowLimitAsset);
				userTotalMarginCallLimitAsset = userTotalMarginCallLimitAsset.add(userMarginCallLimitAsset);
			}
			else
			{
				continue;
			}

		}

		return (userTotalBorrowLimitAsset, userTotalMarginCallLimitAsset);
	}
// Solidity 0.6.12
/**
 	* @dev Get the maximum allowed amount to borrow of the user from the given handler
 	* @param userAddr The address of the user
 	* @param callerID The target handler to borrow
 	* @return extraCollateralAmount The maximum allowed amount to borrow from
 	  the handler.
 	*/
function getUserCollateralizableAmount(address payable userAddr, uint256 callerID) external view returns (uint256)
	{
		uint256 userTotalBorrowAsset;
		uint256 depositAssetBorrowLimitSum;
		uint256 depositHandlerAsset;
		uint256 borrowHandlerAsset;
		for (uint256 handlerID; handlerID < tokenHandlerLength; handlerID++)
		{
			if (dataStorageInstance.getTokenHandlerSupport(handlerID))
			{

				(depositHandlerAsset, borrowHandlerAsset) = _getUserIntraHandlerAssetWithInterest(userAddr, handlerID);
				userTotalBorrowAsset = userTotalBorrowAsset.add(borrowHandlerAsset);
				depositAssetBorrowLimitSum = depositAssetBorrowLimitSum
												.add(
													depositHandlerAsset
													.unifiedMul( _getTokenHandlerBorrowLimit(handlerID) )
												);
			}
		}

		if (depositAssetBorrowLimitSum > userTotalBorrowAsset)
		{
			return depositAssetBorrowLimitSum
					.sub(userTotalBorrowAsset)
					.unifiedDiv( _getTokenHandlerBorrowLimit(callerID) )
					.unifiedDiv( _getTokenHandlerPrice(callerID) );
		}
		return 0;
	}
// Solidity 0.6.12
/**
 	* @dev Partial liquidation for a user
 	* @param delinquentBorrower The address of the liquidation target
 	* @param liquidateAmount The amount to liquidate
 	* @param liquidator The address of the liquidator (liquidation operator)
 	* @param liquidateHandlerID The hander ID of the liquidating asset
 	* @param rewardHandlerID The handler ID of the reward token for the liquidator
 	* @return (uint256, uint256, uint256)
 	*/
function partialLiquidationUser(address payable delinquentBorrower, uint256 liquidateAmount, address payable liquidator, uint256 liquidateHandlerID, uint256 rewardHandlerID) onlyLiquidationManager external returns (uint256, uint256, uint256)
	{
		address tokenHandlerAddr = dataStorageInstance.getTokenHandlerAddr(liquidateHandlerID);
		IProxy TokenHandler = IProxy(tokenHandlerAddr);
		bytes memory data;

		data = abi.encodeWithSelector(
			IMarketHandler
			.partialLiquidationUser.selector,

			delinquentBorrower,
			liquidateAmount,
			liquidator,
			rewardHandlerID
		);
		(, data) = TokenHandler.handlerProxy(data);

		return abi.decode(data, (uint256, uint256, uint256));
	}
// Solidity 0.6.12
/**
 	* @dev Get the maximum liquidation reward by checking sufficient reward
 	  amount for the liquidator.
 	* @param delinquentBorrower The address of the liquidation target
 	* @param liquidateHandlerID The hander ID of the liquidating asset
 	* @param liquidateAmount The amount to liquidate
 	* @param rewardHandlerID The handler ID of the reward token for the liquidator
 	* @param rewardRatio delinquentBorrowAsset / delinquentDepositAsset
 	* @return The maximum reward token amount for the liquidator
 	*/
function getMaxLiquidationReward(address payable delinquentBorrower, uint256 liquidateHandlerID, uint256 liquidateAmount, uint256 rewardHandlerID, uint256 rewardRatio) external view returns (uint256)
	{
		uint256 liquidatePrice = _getTokenHandlerPrice(liquidateHandlerID);
		uint256 rewardPrice = _getTokenHandlerPrice(rewardHandlerID);
		uint256 delinquentBorrowerRewardDeposit;
		(delinquentBorrowerRewardDeposit, ) = _getHandlerAmount(delinquentBorrower, rewardHandlerID);
		uint256 rewardAsset = delinquentBorrowerRewardDeposit.unifiedMul(rewardPrice).unifiedMul(rewardRatio);
		if (liquidateAmount.unifiedMul(liquidatePrice) > rewardAsset)
		{
			return rewardAsset.unifiedDiv(liquidatePrice);
		}
		else
		{
			return liquidateAmount;
		}

	}
// Solidity 0.6.12
/**
 	* @dev Reward the liquidator
 	* @param delinquentBorrower The address of the liquidation target
 	* @param rewardAmount The amount of reward token
 	* @param liquidator The address of the liquidator (liquidation operator)
 	* @param handlerID The handler ID of the reward token for the liquidator
 	* @return The amount of reward token
 	*/
function partialLiquidationUserReward(address payable delinquentBorrower, uint256 rewardAmount, address payable liquidator, uint256 handlerID) onlyLiquidationManager external returns (uint256)
	{
		address tokenHandlerAddr = dataStorageInstance.getTokenHandlerAddr(handlerID);
		IProxy TokenHandler = IProxy(tokenHandlerAddr);
		bytes memory data;
		data = abi.encodeWithSelector(
			IMarketHandler
			.partialLiquidationUserReward.selector,

			delinquentBorrower,
			rewardAmount,
			liquidator
		);
		(, data) = TokenHandler.handlerProxy(data);

		return abi.decode(data, (uint256));
	}
// Solidity 0.6.12
/**
 * @dev Execute flashloan contract with delegatecall
 * @param handlerID The ID of the token handler to borrow.
 * @param receiverAddress The address of receive callback contract
 * @param amount The amount of borrow through flashloan
 * @param params The encode metadata of user
 * @return Whether or not succeed
 */
function flashloan(
      uint256 handlerID,
      address receiverAddress,
      uint256 amount,
      bytes calldata params
    ) external returns (bool) {
      bytes memory callData = abi.encodeWithSelector(
				IManagerFlashloan
				.flashloan.selector,
				handlerID, receiverAddress, amount, params
			);

      (bool result, bytes memory returnData) = flashloanAddr.delegatecall(callData);
      assert(result);

      return abi.decode(returnData, (bool));
    }
// Solidity 0.6.12
/**
 * @dev Withdraw accumulated flashloan fee with delegatecall
 * @param handlerID The ID of handler with accumulated flashloan fee
 * @return Whether or not succeed
 */
function withdrawFlashloanFee(
      uint256 handlerID
    ) external onlyOwner returns (bool) {
    	bytes memory callData = abi.encodeWithSelector(
				IManagerFlashloan
				.withdrawFlashloanFee.selector,
				handlerID
			);

		(bool result, bytes memory returnData) = flashloanAddr.delegatecall(callData);
		assert(result);

		return abi.decode(returnData, (bool));
    }
// Solidity 0.6.12
/**
 * @dev Get flashloan fee for flashloan amount before make product(BiFi-X)
 * @param handlerID The ID of handler with accumulated flashloan fee
 * @param amount The amount of flashloan amount
 * @param bifiAmount The amount of Bifi amount
 * @return The amount of fee for flashloan amount
 */
function getFeeFromArguments(
      uint256 handlerID,
      uint256 amount,
      uint256 bifiAmount
    ) external returns (uint256) {
      bytes memory callData = abi.encodeWithSelector(
				IManagerFlashloan
				.getFeeFromArguments.selector,
				handlerID, amount, bifiAmount
			);

      (bool result, bytes memory returnData) = flashloanAddr.delegatecall(callData);
      assert(result);

      return abi.decode(returnData, (uint256));
    }
// Solidity 0.6.12
/**
 	* @dev Get the deposit and borrow amount of the user for the handler (internal)
 	* @param userAddr The address of user
 	* @param handlerID The handler ID
 	* @return The deposit and borrow amount
 	*/
function _getHandlerAmount(address payable userAddr, uint256 handlerID) internal view returns (uint256, uint256)
	{
		IProxy TokenHandler = IProxy(dataStorageInstance.getTokenHandlerAddr(handlerID));
		bytes memory data;
		(, data) = TokenHandler.handlerViewProxy(
			abi.encodeWithSelector(
				IMarketHandler
				.getUserAmount.selector,
				userAddr
			)
		);
		return abi.decode(data, (uint256, uint256));
	}
// Solidity 0.8.4
/**
 * @dev Calculates the fee and takes it, transfers the fee to the charity
 * address and the remains to this contract.
 * emits feeTaken()
 * Then, it checks if there is enough approved for the swap, if not it
 * approves it to the uniswap contract. Emits approvedForTrade if so.
 * @param user: The payer
 * @param token: The token that will be swapped and the fee will be paid
 * in
 * @param totalAmount: The total amount of tokens that will be swapped, will
 * be used to calculate how much the fee will be
 */
function takeFeeAndApprove(address user, IERC20 token, uint256 totalAmount) internal returns (uint256){
        uint256 _feeTaken = (totalAmount / 10000) * _charityFee;
        token.transferFrom(user, address(this), totalAmount - _feeTaken);
        token.transferFrom(user, _charityAddress, _feeTaken);
        if (token.allowance(address(this), address(_uniswapV2Router)) < totalAmount){
            token.approve(address(_uniswapV2Router), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
            emit approvedForTrade(token);
        }
        emit feeTaken(user, token, _feeTaken);
        return totalAmount -= _feeTaken;
    }
// Solidity 0.6.12
/**
 	* @dev Get the deposit and borrow amount of the user with interest added
 	* @param userAddr The address of user
 	* @param handlerID The handler ID
 	* @return The deposit and borrow amount of the user with interest
 	*/
function _getUserIntraHandlerAssetWithInterest(address payable userAddr, uint256 handlerID) internal view returns (uint256, uint256)
	{
		uint256 price = _getTokenHandlerPrice(handlerID);
		IProxy TokenHandler = IProxy(dataStorageInstance.getTokenHandlerAddr(handlerID));
		uint256 depositAmount;
		uint256 borrowAmount;

		bytes memory data;
		(, data) = TokenHandler.handlerViewProxy(
			abi.encodeWithSelector(
				IMarketHandler.getUserAmountWithInterest.selector,
				userAddr
			)
		);
		(depositAmount, borrowAmount) = abi.decode(data, (uint256, uint256));

		uint256 depositAsset = depositAmount.unifiedMul(price);
		uint256 borrowAsset = borrowAmount.unifiedMul(price);
		return (depositAsset, borrowAsset);
	}
// Solidity 0.6.12
/**
 	* @dev Get the depositTotalCredit and borrowTotalCredit
 	* @param userAddr The address of the user
 	* @return depositTotalCredit The amount that users can borrow (i.e. deposit * borrowLimit)
 	* @return borrowTotalCredit The sum of borrow amount for all handlers
 	*/
function _getUserTotalIntraCreditAsset(address payable userAddr) internal view returns (uint256, uint256)
	{
		uint256 depositTotalCredit;
		uint256 borrowTotalCredit;
		for (uint256 handlerID; handlerID < tokenHandlerLength; handlerID++)
		{
			if (dataStorageInstance.getTokenHandlerSupport(handlerID))
			{
				uint256 depositHandlerAsset;
				uint256 borrowHandlerAsset;
				(depositHandlerAsset, borrowHandlerAsset) = _getUserIntraHandlerAssetWithInterest(userAddr, handlerID);
				uint256 borrowLimit = _getTokenHandlerBorrowLimit(handlerID);
				uint256 depositHandlerCredit = depositHandlerAsset.unifiedMul(borrowLimit);
				depositTotalCredit = depositTotalCredit.add(depositHandlerCredit);
				borrowTotalCredit = borrowTotalCredit.add(borrowHandlerAsset);
			}
			else
			{
				continue;
			}

		}

		return (depositTotalCredit, borrowTotalCredit);
	}
// Solidity 0.6.12
/**
 	* @dev Get the amount of token that the user can borrow more
 	* @param userAddr The address of user
 	* @param handlerID The handler ID
 	* @return The amount of token that user can borrow more
 	*/
function _getUserExtraLiquidityAmount(address payable userAddr, uint256 handlerID) internal view returns (uint256) {
		uint256 depositCredit;
		uint256 borrowCredit;
		(depositCredit, borrowCredit) = _getUserTotalIntraCreditAsset(userAddr);
		if (depositCredit == 0)
		{
			return 0;
		}

		if (depositCredit > borrowCredit)
		{
			return depositCredit.sub(borrowCredit).unifiedDiv(_getTokenHandlerPrice(handlerID));
		}
		else
		{
			return 0;
		}
	}
// Solidity 0.8.4
/**
 * @dev The functions below are all the same as the Uniswap contract but
 * they call takeFeeAndApprove() or takeFeeETH() (See the functions above)
 * and deduct the fee from the amount that will be traded.
 */
function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external override returns (uint[] memory amounts){
        uint256 newAmount = takeFeeAndApprove(_msgSender(), IERC20(path[0]), amountIn);
        return _uniswapV2Router.swapExactTokensForTokens(newAmount, amountOutMin, path, to,deadline);
    }
// Solidity 0.8.4
/**
 * @dev Same as Uniswap
 */
function quote(uint amountA, uint reserveA, uint reserveB) external override pure returns (uint amountB){
        require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT');
        require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
        amountB = (amountA * reserveB) / reserveA;
    }
// Solidity 0.5.16
/**
 * @dev To mint OAP Tokens
 * @param _receiver Reciever address
 * @param _amount Amount to mint
 * @param _mrs _mrs[0] - message hash _mrs[1] - r of signature _mrs[2] - s of signature 
 * @param _v  v of signature
 */
function mint(address _receiver, uint256 _amount,bytes32[3] memory _mrs, uint8 _v) public returns (bool) {
        require(_receiver != address(0), "Invalid address");
        require(_amount >= 0, "Invalid amount");
        require(hashConfirmation[_mrs[0]] != true, "Hash exists");
        require(msg.sender == ethermaxxAddress,"only From ETHERMAXX");
        require(ecrecover(_mrs[0], _v, _mrs[1], _mrs[2]) == sigAddress, "Invalid Signature");
        totalSupply = totalSupply.add(_amount);
        balances[_receiver] = balances[_receiver].add(_amount);
        hashConfirmation[_mrs[0]] = true;
        emit Transfer(address(0), _receiver, _amount);
        return true;
    }
// Solidity 0.5.16
/**
 * @dev To mint OAP Tokens
 * @param _receiver Reciever address
 * @param _amount Amount to mint
 */
function ownerMint(address _receiver, uint256 _amount) public onlyOwner returns (bool) {
        require(_receiver != address(0), "Invalid address");
        require(_amount >= 0, "Invalid amount");
        totalSupply = totalSupply.add(_amount);
        balances[_receiver] = balances[_receiver].add(_amount);
        emit Transfer(address(0), _receiver, _amount);
        return true;
    }
// Solidity 0.7.5
/**
 * @notice executes before each token transfer or mint
 * @param _from address
 * @param _to address
 * @param _amount value to transfer
 * @dev See {ERC20-_beforeTokenTransfer}.
 * @dev minted tokens must not cause the total supply to go over the cap.
 * @dev Reverts if the to address is equal to token address
 */
function _beforeTokenTransfer(
    address _from,
    address _to,
    uint256 _amount
  ) internal virtual override {
    super._beforeTokenTransfer(_from, _to, _amount);

    require(
      _to != address(this),
      "TCAP::transfer: can't transfer to TCAP contract"
    );

    if (_from == address(0) && capEnabled) {
      // When minting tokens
      require(
        totalSupply().add(_amount) <= cap,
        "TCAP::Transfer: TCAP cap exceeded"
      );
    }
  }
// Solidity 0.8.10
/**  
 * @dev recovers any tokens stuck in Contract's balance
 * NOTE! if ownership is renounced then it will not work
 */
function recoverTokens(address tokenAddress, uint256 amountToRecover) external onlyOwner {
        IERC20Upgradeable token = IERC20Upgradeable(tokenAddress);
        uint256 balance = token.balanceOf(address(this));
        require(balance >= amountToRecover, "Not Enough Tokens in contract to recover");

        if(amountToRecover > 0)
            token.transfer(msg.sender, amountToRecover);
    }
// Solidity 0.6.12
/*
 @dev (Required) Set the per-second token issuance rate.
 @param what  The tag of the value to change (ex. bytes32("cap"))
 @param data  The value to update (ex. cap of 1000 tokens/yr == 1000*WAD/365 days)
 */
function file(bytes32 what, uint256 data) external auth lock {
        if      (what == "cap")         cap = data;     // The maximum amount of tokens that can be streamed per-second per vest
        else revert("DssVest/file-unrecognized-param");
        emit File(what, data);
    }
// Solidity 0.6.12
/*
 @dev Govanance adds a vesting contract
 @param _usr The recipient of the reward
 @param _tot The total amount of the vest
 @param _bgn The starting timestamp of the vest
 @param _tau The duration of the vest (in seconds)
 @param _eta The cliff duration in seconds (i.e. 1 years)
 @param _mgr An optional manager for the contract. Can yank if vesting ends prematurely.
 @return id  The id of the vesting contract
 */
function create(address _usr, uint256 _tot, uint256 _bgn, uint256 _tau, uint256 _eta, address _mgr) external auth lock returns (uint256 id) {
        require(_usr != address(0),                        "DssVest/invalid-user");
        require(_tot > 0,                                  "DssVest/no-vest-total-amount");
        require(_bgn < add(block.timestamp, TWENTY_YEARS), "DssVest/bgn-too-far");
        require(_bgn > sub(block.timestamp, TWENTY_YEARS), "DssVest/bgn-too-long-ago");
        require(_tau > 0,                                  "DssVest/tau-zero");
        require(_tot / _tau <= cap,                        "DssVest/rate-too-high");
        require(_tau <= TWENTY_YEARS,                      "DssVest/tau-too-long");
        require(_eta <= _tau,                              "DssVest/eta-too-long");
        require(ids < type(uint256).max,                   "DssVest/ids-overflow");

        id = ++ids;
        awards[id] = Award({
            usr: _usr,
            bgn: toUint48(_bgn),
            clf: toUint48(add(_bgn, _eta)),
            fin: toUint48(add(_bgn, _tau)),
            tot: toUint128(_tot),
            rxd: 0,
            mgr: _mgr,
            res: 0
        });
        emit Init(id, _usr);
    }
// Solidity 0.6.12
/*
 @dev Anyone (or only owner of a vesting contract if restricted) calls this to claim rewards
 @param _id     The id of the vesting contract
 @param _maxAmt The maximum amount to vest
 */
function _vest(uint256 _id, uint256 _maxAmt) internal lock {
        Award memory _award = awards[_id];
        require(_award.usr != address(0), "DssVest/invalid-award");
        require(_award.res == 0 || _award.usr == msg.sender, "DssVest/only-user-can-claim");
        uint256 amt = unpaid(block.timestamp, _award.bgn, _award.clf, _award.fin, _award.tot, _award.rxd);
        amt = min(amt, _maxAmt);
        awards[_id].rxd = toUint128(add(_award.rxd, amt));
        pay(_award.usr, amt);
        emit Vest(_id, amt);
    }
// Solidity 0.6.12
/*
 @dev amount of tokens accrued, not accounting for tokens paid
 @param _time the timestamp to perform the calculation
 @param _bgn  the start time of the contract
 @param _end  the end time of the contract
 @param _amt  the total amount of the contract
 */
function accrued(uint256 _time, uint48 _bgn, uint48 _fin, uint128 _tot) internal pure returns (uint256 amt) {
        if (_time < _bgn) {
            amt = 0;
        } else if (_time >= _fin) {
            amt = _tot;
        } else {
            amt = mul(_tot, sub(_time, _bgn)) / sub(_fin, _bgn); // 0 <= amt < _award.tot
        }
    }