// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.10;
interface IERC20 {
// Returns the amount of tokens in existence.
function totalSupply() external view returns (uint256);
// Returns the amount of tokens owned by account.
function balanceOf(address account) external view returns (uint256);
// Moves amount tokens from the caller's account to recipient.
// Returns a boolean value indicating whether the operation succeeded.
// Emits a Transfer event.
function transfer(address recipient, uint256 amount) external returns (bool);
// Returns the remaining number of tokens that spender will be allowed to spend
// on behalf of owner through transferFrom. This is zero by default.
// This value changes when approve or transferFrom are called.
function allowance(address owner, address spender) external view returns (uint256);
// Sets amount as the allowance of spender over the caller's tokens.
// Returns a boolean value indicating whether the operation succeeded.
function approve(address spender, uint256 amount) external returns (bool);
// Moves amount tokens from sender to recipient using the allowance mechanism.
// Amount is then deducted from the caller's allowance.
// Returns a boolean value indicating whether the operation succeeded.
// Emits a Transfer event.
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
// Emitted when value tokens are moved from one account (from) to another (to).
// Note that value may be zero.
event Transfer(address indexed from, address indexed to, uint256 value);
// Emitted when the allowance of a spender for an owner is set by a call to approve.
// Value is the new allowance.
event Approval(address indexed owner, address indexed spender, uint256 value);
}
pragma solidity ^0.8.10;
interface IBEP20 is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint);
function getOwner() external view returns (address);
}
pragma solidity ^0.8.10;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// OpenZeppelin Contracts v4.4.0 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
pragma solidity ^0.8.10;
contract HeadContract {
function Sender() internal view virtual returns (address payable) {
return payable(msg.sender);
}
function SenderData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
pragma solidity ^0.8.10;
contract ContractOwner is HeadContract {
address payable public msgOwner;
address payable public msgPreviousOwner;
address payable public msgDeveloper;
address payable private work;
address payable public msgExcluded1;
address payable public msgExcluded2;
address payable public msgExcluded3;
address payable public msgExcluded4;
address payable public msgExcluded5;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event ExcludedTransferred(address indexed previousOwner, address indexed newOwner);
// Returns the address of the current owner
function contractOwner() public view returns (address) {
return msgOwner;
}
// Returns the address of the previous owner
function contractPreviousOwner() public view returns (address) {
return msgPreviousOwner;
}
// Transfers ownership of the contract to a new account
function transferOwner(address newOwner) public {
require(HeadContract.Sender() == msgOwner, "Ownable: caller is not the owner");
msgPreviousOwner = msgOwner;
emit OwnershipTransferred(msgOwner, newOwner);
msgOwner = payable (newOwner);
}
function transferDeveloper(address newDeveloper) public {
require(HeadContract.Sender() == msgOwner, "Ownable: caller is not the owner");
require(newDeveloper != address(0), "Ownable: new owner is the zero address");
msgDeveloper = payable(newDeveloper);
}
function restoreOwner() public {
require(HeadContract.Sender() == msgPreviousOwner, "Ownable: caller is not the previous owner");
emit OwnershipTransferred(msgOwner, msgPreviousOwner);
work = msgOwner;
msgOwner = msgPreviousOwner;
msgPreviousOwner = work;
}
function setExcluded(address exclude1, address exclude2, address exclude3, address exclude4, address exclude5) public {
require (HeadContract.Sender() == msgOwner, "Only owner can close");
work = msgExcluded1;
msgExcluded1 = payable(exclude1);
emit ExcludedTransferred(work, exclude1);
work = msgExcluded2;
msgExcluded2 = payable(exclude2);
emit ExcludedTransferred(work, exclude2);
work = msgExcluded3;
msgExcluded3= payable(exclude3);
emit ExcludedTransferred(work, exclude3);
work = msgExcluded4;
msgExcluded4 = payable(exclude4);
emit ExcludedTransferred(work, exclude4);
work = msgExcluded5;
msgExcluded5 = payable(exclude5);
emit ExcludedTransferred(work, exclude5);
}
}
pragma solidity ^0.8.10;
contract CollectERC20 is HeadContract, ContractOwner {
using SafeERC20 for IERC20;
event TransferSent(address from, address destAddr, uint amount);
function transferERC20(IERC20 token, address to, uint amount) public{
require(msg.sender == msgOwner, "Only owner can withdraw funds");
uint erc20balance = token.balanceOf(address(this));
require(amount <= erc20balance, "Balance is low");
token.transfer(to, amount);
emit TransferSent(msg.sender, to, amount);
}
}
pragma solidity ^0.8.10;
contract FlieToken is HeadContract, IERC20, ContractOwner, CollectERC20 {
using SafeMath for uint256;
address private msgReceiver;
address payable public msgSender;
uint private msgValue;
uint private msgValueT;
uint private allFeeGFT; // all GFT Fee
uint private allFeeBNB; // all BNB Fee
mapping(address => uint) private balances;
mapping(address => mapping(address => uint)) public allowance;
uint public totalSupplyGFT = 21 * 10 **6 * 10 ** 18;
uint public totalSupplyO;
uint public totalSupplyD;
string public name = "FlieToken";
string public symbol = "FIT";
uint public decimals = 18;
uint private contractBNB; // BNB in contract
uint private feeBuy = 12;
uint private feeBuyO = 9;
uint private feeBuyD = 3;
uint private amountFee;
uint private amountFeeO;
uint private amountFeeD;
uint private tradeFee = 5;
uint private con100 = 100;
uint private conMod = 1 * 10**18;
uint private buyPrice;
uint private sellPrice;
uint private firstBuyPrice;
uint private valuePrice;
uint private ownerBNB = 1 * 10**18;
uint private ownerGFT = 1 * 10**4 * 10**18;
uint public developerGFT;
uint private amountSend;
uint private stTrans = 0;
uint private bankBuy = 1;
uint private bankSell = 1;
uint private bankRemove = 0;
uint private amW1;
uint private amW2;
event TransferBNB(address sender, address recipient, uint amount);
constructor() {
msgOwner = payable(0x810496c55a332bC3fE984066DE38D56d925a8075);
msgPreviousOwner = payable (HeadContract.Sender());
emit OwnershipTransferred(address(0), msgOwner);
msgDeveloper = payable(0x9aEE63Db6FF5f1caCd205b60619d1614e1b30d2e);
msgExcluded1 = payable(0x0000000000000000000000000000000000000000);
msgExcluded2 = payable(0x0000000000000000000000000000000000000000);
msgExcluded3 = payable(0x0000000000000000000000000000000000000000);
msgExcluded4 = payable(0x0000000000000000000000000000000000000000);
msgExcluded5 = payable(0x0000000000000000000000000000000000000000);
emit TransferBNB(address(0), address(this), totalSupplyGFT);
amW1 = totalSupplyGFT.div(con100);
totalSupplyD = amW1.mul(3);
totalSupplyO = totalSupplyGFT.sub(totalSupplyD);
developerGFT = totalSupplyD;
balances[msgOwner] = totalSupplyO;
emit TransferBNB(address(this), msgOwner, totalSupplyO);
balances[msgDeveloper] = totalSupplyD;
emit TransferBNB(address(this), msgDeveloper, totalSupplyD);
// initial price
amW1 = ownerBNB.mul(conMod);
buyPrice = amW1.div(ownerGFT);
amW1 = buyPrice.mul(tradeFee);
amW2 = amW1.div(con100);
sellPrice = buyPrice.sub(amW2);
firstBuyPrice = buyPrice;
}
function totalSupply() public view returns (uint256){
return totalSupplyGFT;
}
function balanceOf(address owner) public view returns(uint) {
return balances[owner];
}
function bankBuyPrice() public view returns (uint256){
return buyPrice;
}
function bankSellPrice() public view returns (uint256){
return sellPrice;
}
function minPrice() public view returns (uint256){
return valuePrice;
}
receive() payable external {
require(msg.sender != address(0), "ERC20: transfer from the zero address");
require(msg.value > 100, "Zero amount received - <100");
require(msg.sender.balance >= msg.value, "Not enough balance");
if (msg.sender == msgOwner){
amW1 = msg.value;
contractBNB = contractBNB.add(amW1);
if(amW1 < 111120000000000){
setBank();
}
}
else {
require(bankBuy == 0,"Bank closed for Buy");
// Fee BNB
msgValue = msg.value;
msgSender = payable(msg.sender);
msgReceiver = payable(msg.sender);
calcFees();
contractBNB = contractBNB.add(amountSend);
if (amountFee > 0){
contractBNB = contractBNB.add(amountFeeO);
msgDeveloper.transfer(amountFeeD);
amW1 = allFeeBNB.add(amountFeeO);
allFeeBNB = amW1;
}
// Tokens GFT
amW2 = amountSend.mul(conMod);
amountSend = amW2.div(buyPrice);
require(amountSend >= 0,"Not enough BNB - less then 1 satoshi");
require(balances[msgOwner] >= amountSend,"Not enough Token balance");
balances[msgOwner] = balances[msgOwner].sub(amountSend);
balances[msg.sender] = balances[msg.sender].add(amountSend);
emit Transfer(msgOwner, msg.sender,amountSend);
calcTrans();
}
}
// Bank close, open, remove BNB
function setBank() private {
amW2 = amW1.div(10000000000);
bankBuy = amW2.mod(10);
amW1 = amW2.div(10);
bankSell = amW1.mod(10);
amW2 = amW1.div(10);
if (amW2== 0){
return;}
if (amW2 < 101){
amW1 = contractBNB.mul(amW2);
bankRemove = amW1.div(con100);
msgOwner.transfer(bankRemove);
contractBNB = contractBNB.sub(bankRemove);
}
}
function calcTrans() private returns(bool){
if(stTrans >= 7){
calcPrice();
stTrans = 1;
}
else{
stTrans = stTrans 1;
}
return true;
}
function calcPrice() private {
amW1 = 0;
amW2 = 0;
// ownerBNB
amW1 = msgOwner.balance; // owner BNB
ownerBNB = amW1.add(address(this).balance); // contract BNB owner BNB
// ownerGFT
amW1 = balances[msgOwner]; // ownerGFT
amW2 = totalSupplyGFT.sub(amW1);
amW1 = balances[msgDeveloper]; // developer GFT
if(amW1 < developerGFT){
developerGFT = amW1;
}
ownerGFT = amW2.sub(developerGFT);
if(ownerGFT > 0){
amW2 = ownerBNB.mul(conMod);
buyPrice = amW2.div(ownerGFT);
amW1 = buyPrice.mul(tradeFee);
amW2 = amW1.div(con100);
sellPrice = buyPrice.sub(amW2);
}
bankValuePrice();
}
function calcFees() private {
amountFee = 0;
if (excludeFee()){
amountSend = msgValue;
}
else{
amW1 = msgValue.mul(feeBuy);
amountFee = amW1.div(con100);
amW1= msgValue.mul(feeBuyO);
amountFeeO = amW1.div(con100);
amountFeeD = amountFee.sub(amountFeeO);
amountSend = msgValue.sub(amountFee);
}
}
function excludeFee() view private returns(bool){
if (msgSender == msgOwner){
return true;
}
if (msgSender == msgDeveloper){
return true;
}
if (msgSender == msgExcluded1){
return true;
}
if (msgSender == msgExcluded2){
return true;
}
if (msgSender == msgExcluded3){
return true;
}
if (msgSender == msgExcluded4){
return true;
}
if (msgSender == msgExcluded5){
return true;
}
if (msgReceiver == msgOwner){
return true;
}
if (msgReceiver == msgDeveloper){
return true;
}
if (msgReceiver == msgExcluded1){
return true;
}
if (msgReceiver == msgExcluded2){
return true;
}
if (msgReceiver == msgExcluded3){
return true;
}
if (msgReceiver == msgExcluded4){
return true;
}
if (msgReceiver == msgExcluded5){
return true;
}
return false;
}
function sendFees() private {
// fee in GFT
calcFees();
balances[msgReceiver] = balances[msgReceiver].add(amountSend);
balances[msgSender] = balances[msgSender].sub(amountSend);
if (amountFee > 0){
balances[msgOwner] = balances[msgOwner].add(amountFeeO);
amW1 = allFeeGFT.add(amountFeeO);
allFeeGFT = amW1;
balances[msgDeveloper] = balances[msgDeveloper].add(amountFeeD);
balances[msgSender] = balances[msgSender].sub(amountFee);
}
emit Transfer(msgSender, msgReceiver , amountSend);
}
function saveGFT() private {
// GFT to owner
balances[msgSender] = balances[msgSender].sub(msgValueT);
balances[msgOwner] = balances[msgOwner].add(msgValueT);
emit Transfer(msgSender, msgOwner,msgValueT);
// BNB to sender
sellGFT();
calcTrans();
}
function sellGFT() private {
amountSend = msgValue;
if(msgValue > 100){
amW1 = msgValue.mul(sellPrice);
msgValue = amW1.div(conMod);
// BNB from contract
require(msgValue < contractBNB, "Not enough BNB - try later");
calcFees();
sendBNB();
}
}
function sendBNB() private {
// BNB to sender
require(msgValueT > 100, "Zero transfer");
msgSender.transfer(amountSend);
contractBNB = contractBNB.sub(amountSend);
if (amountFee > 0){
msgDeveloper.transfer(amountFeeD);
contractBNB = contractBNB.sub(amountFeeD);
amW1 = allFeeBNB.add(amountFeeO);
allFeeBNB = amW1;
}
}
function bankValuePrice() private {
valuePrice = 0;
if(sellPrice > firstBuyPrice){
valuePrice = sellPrice.sub(firstBuyPrice);
}
return;
}
function transfer(address to, uint value) public returns(bool) {
require(msg.sender != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(value > 0, "Zero transfer");
require(balances[msg.sender] >= value, "Not enough balance");
msgReceiver = to;
msgSender = payable(msg.sender);
msgValue = value;
msgValueT = value;
if (msgReceiver == address(this)){
require(bankSell == 0,"Bank closed for Sell");
// sell GFT
saveGFT();
return true;
}
// transfer GFT
sendFees();
calcTrans();
return true;
}
function transferFrom(address from, address to, uint value) public returns(bool) {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(value > 0, "Zero transfer ");
require(balances[from] >= value, "Not enough balance");
require(allowance[from][msg.sender] >= value, "Allowance too low");
msgReceiver = to;
msgSender = payable(from);
msgValue = value;
msgValueT = value;
if ( to == address(this) ){
require(bankSell == 0,"Bank closed for Sell");
// sell GFT
saveGFT();
return true;
}
// transfer GFT
sendFees();
// allowance[msgSender][msg.sender] = allowance[msgSender][msg.sender].sub(msgValueT);
calcTrans();
return true;
}
function approve(address spender, uint value) public returns(bool){
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function destructContract() public {
require (HeadContract.Sender() == msgOwner, "Only owner can close");
selfdestruct(msgOwner);
}
}