// Contract: TELEToken
// Target function: function functionCallWithValue(
// SPDX-License-Identifier: MIT

pragma solidity 0.8.12;

// ----------------------------------------------------------------------------
// 'TELE' token governance smart contract
//
// Symbol      : TELE
// Name        : Telefy
// Max Total Circulating supply: 1000000000
// Decimals    : 18
//
//
//
// (c) by Telefy Technologies Private Limited.
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Safe maths
// ----------------------------------------------------------------------------
/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
contract SafeMath {
	function safeAdd(uint256 a, uint256 b) internal pure returns (uint256 c) {
		c = a + b;
		require(c >= a, "SafeMath: addition overflow");
	}

	function safeSub(uint256 a, uint256 b) internal pure returns (uint256 c) {
		require(b <= a, "SafeMath: subtraction overflow");
		c = a - b;
	}

	function safeMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
		if (a == 0) {
			c = 0;
		} else {
			c = a * b;
		}
		require((a == 0 || c / a == b), "SafeMath: multiplication overflow");
	}

	function safeDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
		require(b > 0, "SafeMath: division by zero");
		c = a / b;
	}

	function safeMod(uint256 a, uint256 b) internal pure returns (uint256 c) {
		require(b != 0, "SafeMath: modulo by zero");
		c = a % b;
	}
}

// ----------------------------------------------------------------------------
// Information of context: Sender and Data
// ----------------------------------------------------------------------------
abstract contract Context {
	function _msgSender() internal view virtual returns (address) {
		return msg.sender;
	}

	function _msgData() internal view virtual returns (bytes memory) {
		this; // Warning: silence state mutability without generating bytecode
		return msg.data;
	}
}

// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ----------------------------------------------------------------------------
abstract contract ERC20Interface {
	function totalSupply() public view virtual returns (uint256);

	function balanceOf(address tokenOwner) public view virtual returns (uint256 balance);

	function allowance(address tokenOwner, address spender)
		public
		view
		virtual
		returns (uint256 remaining);

	function transfer(address to, uint256 tokens) external virtual returns (bool success);

	function approve(address spender, uint256 tokens) public virtual returns (bool success);

	function transferFrom(
		address from,
		address to,
		uint256 tokens
	) external virtual returns (bool success);

	event Transfer(address indexed from, address indexed to, uint256 tokens);
	event Approval(address indexed tokenOwner, address indexed spender, uint256 tokens);
}

// ----------------------------------------------------------------------------
// Contract function to receive approval and execute function in one call
//
// Borrowed from MiniMeToken
// ----------------------------------------------------------------------------
abstract contract ApproveAndCallFallBack {
	function receiveApproval(
		address from,
		uint256 tokens,
		address token,
		bytes memory data
	) public virtual;
}

// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
	address public owner;
	address public newOwner;

	event OwnershipTransferred(address indexed _from, address indexed _to);

	constructor() {
		owner = msg.sender;
	}

	modifier onlyOwner() {
		require(msg.sender == owner);
		_;
	}

	function transferOwnership(address _newOwner) external onlyOwner {
		newOwner = _newOwner;
	}

	function acceptOwnership() external {
		require(msg.sender == newOwner);
		emit OwnershipTransferred(owner, newOwner);
		owner = newOwner;
		newOwner = address(0);
	}
}

// ----------------------------------------------------------------------------
// @dev Collection of functions related to the address type
// @openzeppelin/contracts/utils/Address.sol
// ----------------------------------------------------------------------------
library Address {
	// ----------------------------------------------------------------------------
	// @dev Returns true if `account` is a contract.
	//
	// [IMPORTANT]
	// It is unsafe to assume that an address for which this function returns
	// false is an externally-owned account (EOA) and not a contract.
	//
	// Among others, `isContract` will return false for the following
	// types of addresses:
	//
	//  - an externally-owned account
	//  - a contract in construction
	//  - an address where a contract will be created
	//  - an address where a contract lived, but was destroyed
	// ----------------------------------------------------------------------------
	function isContract(address account) internal view returns (bool) {
		// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
		// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
		// for accounts without code, i.e. `keccak256('')`
		bytes32 codehash;
		bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
		// solhint-disable-next-line no-inline-assembly
		assembly {
			codehash := extcodehash(account)
		}
		return (codehash != accountHash && codehash != 0x0);
	}

	// ----------------------------------------------------------------------------
	// @dev Replacement for Solidity's `transfer`: sends `amount` wei to
	// `recipient`, forwarding all available gas and reverting on errors.
	//
	// https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
	// of certain opcodes, possibly making contracts go over the 2300 gas limit
	// imposed by `transfer`, making them unable to receive funds via
	// `transfer`. {sendValue} removes this limitation.
	//
	// https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
	//
	// IMPORTANT: because control is transferred to `recipient`, TELEe must be
	// taken to not create reentrancy vulnerabilities. Consider using
	// {ReentrancyGuard} or the
	// https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
	// ----------------------------------------------------------------------------
	function sendValue(address payable recipient, uint256 amount) internal {
		require(address(this).balance >= amount, "Address: insufficient balance");

		// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
		(bool success, ) = recipient.call{ value: amount }("");
		require(success, "Address: unable to send value, recipient may have reverted");
	}

	// ----------------------------------------------------------------------------
	// @dev Performs a Solidity function call using a low level `call`. A
	// plain`call` is an unsafe replacement for a function call: use this
	// function instead.
	//
	// If `target` reverts with a revert reason, it is bubbled up by this
	// function (like regular Solidity function calls).
	//
	// Returns the raw returned data. To convert to the expected return value,
	// use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
	// _Available since v3.1._
	// ----------------------------------------------------------------------------
	function functionCall(address target, bytes memory data) internal returns (bytes memory) {
		return functionCall(target, data, "Address: low-level call failed");
	}

	// ----------------------------------------------------------------------------
	// @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
	// `errorMessage` as a fallback revert reason when `target` reverts.
	// _Available since v3.1._
	// ----------------------------------------------------------------------------
	function functionCall(
		address target,
		bytes memory data,
		string memory errorMessage
	) internal returns (bytes memory) {
		return _functionCallWithValue(target, data, 0, errorMessage);
	}