ETH Price: $2,721.71 (+4.87%)

Transaction Decoder

Block:
20815449 at Sep-23-2024 07:43:47 PM +UTC
Transaction Fee:
0.000761128211360825 ETH $2.07
Gas Used:
34,111 Gas / 22.313277575 Gwei

Emitted Events:

399 Deployyyyer.0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925( 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925, 0x0000000000000000000000009374176ba0e0e56d1f244b2f4ba32a794bf06e0e, 0x000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3, 00000000000000000000000000000000000000000001a7849452cecf4530e0b0 )

Account State Difference:

  Address   Before After State Difference Code
0x3914BDB4...42d19680D
(Titan Builder)
5.173805735879492135 Eth5.173872648922056965 Eth0.00006691304256483
0x9374176B...94BF06e0e
0.111743566875272765 Eth
Nonce: 221
0.11098243866391194 Eth
Nonce: 222
0.000761128211360825

Execution Trace

Deployyyyer.095ea7b3( )
  • NewTokenFacet.approve( spender=0x000000000022D473030F116dDEE9F6B43aC78BA3, amount=2000006680303844904198320 ) => ( True )
    File 1 of 2: Deployyyyer
    // SPDX-License-Identifier: MIT
    /*********************************************************************************************\\
    * Deployyyyer: https://deployyyyer.io
    * Twitter: https://x.com/deployyyyer
    * Telegram: https://t.me/Deployyyyer
    /*********************************************************************************************/
    pragma solidity ^0.8.23;
    import { LibDiamond } from "./libraries/LibDiamond.sol";
    import { IDiamondCut } from "./interfaces/IDiamondCut.sol";
    import "./libraries/LibDiamond.sol";
    import "./interfaces/IDiamondLoupe.sol";
    import "./interfaces/IDiamondCut.sol";
    import "./interfaces/IERC173.sol";
    import "./interfaces/IERC165.sol";
    import "./interfaces/IERC20.sol";
    import { INewToken, IUniswapV2Router02 } from "./interfaces/INewToken.sol";
    import "./libraries/LibAppStorage.sol";
    //import "hardhat/console.sol";
    /// @title Deployyyyer 
    /// @notice Diamond Proxy for Deployyyyer
    /// @dev 
    contract Deployyyyer { 
        AppStorage internal s;
        event Transfer(address indexed from, address indexed to, uint256 value);
        //event Approval(address indexed owner, address indexed spender, uint256 value);
        event FactoryBuilt(string name, string symbol, uint256 supply);
        event TeamSet(INewToken.TeamParams tparams);
        event LaunchCostChanged(uint256 ethCost, uint256 deployyyyerCost);
        event PromoCostChanged(uint256 ethCost, uint256 deployyyyerCost);
        event MinLiquidityChanged(uint256 minLiq);
        event IncreasedLimits(uint256 maxWallet, uint256 maxTx);
        struct ConstructorArgs {
            bool createToken;
            address taxwallet;
            address stakingFacet;
            address presaleFacet;
            address tokenFacet;
            address v2router;
            address team1;
            address team2;
            address team3;
            address marketing;
            address treasury;
            uint256 ethCost;
            uint256 deployyyyerCost;
            uint256 promoCostEth;
            uint256 promoCostDeployyyyer;
            uint256 minLiq;
            address uniswapRouter;
            address sushiswapRouter;
            address pancakeswapRouter;
        }
        /// @notice Constructor of Diamond Proxy for Deployyyyer
        constructor(IDiamondCut.FacetCut[] memory _diamondCut, ConstructorArgs memory _args) {
            if(_args.createToken) {
                emit FactoryBuilt("Deployyyyer", "DEPLOY", 1000000000);
            } else {
                emit FactoryBuilt("Deployyyyer", "DEPLOY", 0);
            }
            LibDiamond.diamondCut(_diamondCut, address(0), new bytes(0));
            //console.log(msg.sender);
            LibDiamond.setContractOwner(msg.sender);
            LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
            // adding ERC165 data
            ds.supportedInterfaces[type(IERC165).interfaceId] = true;
            //ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;
            ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;
            ds.supportedInterfaces[type(IERC173).interfaceId] = true;
            ds.supportedInterfaces[type(IERC20).interfaceId] = true;
            //init appStorage 
            s.stakingFacet = _args.stakingFacet;
            s.presaleFacet = _args.presaleFacet;
            //s.deployyyyer = address(this);
            s.isParent = true;
            s.decimals = 18;
            s.ethCost = _args.ethCost; //2 * 10**s.decimals / 10; //0.2eth
            s.deployyyyerCost = _args.deployyyyerCost; //100000 * 10**s.decimals;
            s.promoCostEth = _args.promoCostEth; //5 * 10**s.decimals / 100; //0.05 eth per hour
            s.promoCostDeployyyyer = _args.promoCostDeployyyyer; //50000 * 10**s.decimals;
            s.minLiq = _args.minLiq; //1 * 10**s.decimals / 10; //0.1eth min
            //s.bridge = address(0);
            emit LaunchCostChanged(s.ethCost, s.deployyyyerCost);
            emit PromoCostChanged(s.promoCostEth, s.promoCostDeployyyyer);
            emit MinLiquidityChanged(s.minLiq);
            s.isFreeTier = false;
            s.taxWallet = payable(_args.taxwallet);
            s.deployyyyerCa = payable(address(this));
            s.tokenFacet = _args.tokenFacet;
            
            s.validRouters[_args.v2router] = true;
            s.validRouters[_args.uniswapRouter] = true;
            s.validRouters[_args.sushiswapRouter] = true;
            s.validRouters[_args.pancakeswapRouter] = true;
            
            if(_args.createToken) {
                
                s.maxBuyTax = 10;
                s.minBuyTax = 2;
                s.taxBuy = s.maxBuyTax; //20%
                
                s.maxSellTax = 10;
                s.minSellTax = 2;
                s.taxSell = s.maxSellTax; //20%
                
                s.initTaxType = 1;
                s.initInterval = 0;
                s.countInterval = 20;
                // Reduction Rules
                s.buyCount = 0; 
                s.name = "Deployyyyer";
                s.symbol = "DEPLOY";
                s.tTotal = 1000000000 * 10**s.decimals; //1b tokens in wei
                // Contract Swap Rules            
                s.taxSwapThreshold = s.tTotal * 1 / 1000; //0.1%
                s.maxTaxSwap = s.tTotal * 1 / 100; //1%
                s.preventSwap = 20;
                s.maxWallet = s.tTotal * 2 / 100;  //2% 
                s.maxTx = s.tTotal * 2 / 100;  //2% 
                s.walletLimited = true;
                s.balances[address(this)] = s.tTotal;
                emit IncreasedLimits(2, 2);
                emit Transfer(address(0), address(this), s.tTotal);
                s.cliffPeriod = 0;
                s.vestingPeriod = 0;
                s.teamShare[_args.team1] = s.tTotal * 4 / 100;
                s.teamShare[_args.team2] = s.tTotal * 3 / 100;
                s.teamShare[_args.team3] = s.tTotal * 3 / 100;
                s.teamShare[_args.marketing] = s.tTotal * 5 / 100; 
                s.teamShare[_args.treasury] = s.tTotal * 5 / 100; 
                s.isExTxLimit[_args.marketing] = true;
                s.isExWaLimit[_args.marketing] = true;
                s.isExTxLimit[_args.treasury] = true;
                s.isExWaLimit[_args.treasury] = true;
                s.isExTxLimit[_args.team1] = true;
                s.isExWaLimit[_args.team1] = true;
                s.isExTxLimit[_args.team2] = true;
                s.isExWaLimit[_args.team2] = true;
                s.isExTxLimit[_args.team3] = true;
                s.isExWaLimit[_args.team3] = true;
                emit TeamSet(INewToken.TeamParams(_args.team1, 4, s.cliffPeriod, s.vestingPeriod, true)); 
                emit TeamSet(INewToken.TeamParams(_args.team2, 3, s.cliffPeriod, s.vestingPeriod, true)); 
                emit TeamSet(INewToken.TeamParams(_args.team3, 3, s.cliffPeriod, s.vestingPeriod, true)); 
                emit TeamSet(INewToken.TeamParams(_args.marketing, 5, s.cliffPeriod, s.vestingPeriod, true));
                emit TeamSet(INewToken.TeamParams(_args.treasury, 5, s.cliffPeriod, s.vestingPeriod, true)); 
                s.teamBalance = s.tTotal * 20 / 100;
                s.uniswapV2Router = IUniswapV2Router02(_args.v2router);
                s.allowances[address(this)][address(s.uniswapV2Router)] = s.tTotal;
                //emit Approval(address(this), address(s.uniswapV2Router), s.tTotal);
                s.launchedTokens[address(this)] = msg.sender; 
            }
            
        }   
        /// @notice fallback
        // Find facet for function that is called and execute the
        // function if a facet is found and return any value.
        fallback() external payable {
            LibDiamond.DiamondStorage storage ds;
            bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
            // get diamond storage
            assembly {
                ds.slot := position
            }
            // get facet from function selector
            address facet = address(bytes20(ds.facets[msg.sig]));
            require(facet != address(0), "S1");
            // Execute external function from facet using delegatecall and return any value.
            assembly {
                // copy function selector and any arguments
                calldatacopy(0, 0, calldatasize())
                // execute function call using the facet
                let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
                // get any return value
                returndatacopy(0, 0, returndatasize())
                // return any return value or error back to the caller
                switch result
                    case 0 {
                        revert(0, returndatasize())
                    }
                    default {
                        return(0, returndatasize())
                    }
            }
        }
        /// @notice receive
        receive() external payable {}
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /******************************************************************************\\
    * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
    * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
    /******************************************************************************/
    interface IDiamondCut {
        enum FacetCutAction {Add, Replace, Remove}
        // Add=0, Replace=1, Remove=2
        struct FacetCut {
            address facetAddress;
            FacetCutAction action;
            bytes4[] functionSelectors;
        }
        /// @notice Add/replace/remove any number of functions and optionally execute
        ///         a function with delegatecall
        /// @param _diamondCut Contains the facet addresses and function selectors
        /// @param _init The address of the contract or facet to execute _calldata
        /// @param _calldata A function call, including function selector and arguments
        ///                  _calldata is executed with delegatecall on _init
        function diamondCut(
            FacetCut[] calldata _diamondCut,
            address _init,
            bytes calldata _calldata
        ) external;
        event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /******************************************************************************\\
    * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
    * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
    /******************************************************************************/
    // A loupe is a small magnifying glass used to look at diamonds.
    // These functions look at diamonds
    interface IDiamondLoupe {
        /// These functions are expected to be called frequently
        /// by tools.
        struct Facet {
            address facetAddress;
            bytes4[] functionSelectors;
        }
        /// @notice Gets all facet addresses and their four byte function selectors.
        /// @return facets_ Facet
        function facets() external view returns (Facet[] memory facets_);
        /// @notice Gets all the function selectors supported by a specific facet.
        /// @param _facet The facet address.
        /// @return facetFunctionSelectors_
        function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);
        /// @notice Get all the facet addresses used by a diamond.
        /// @return facetAddresses_
        function facetAddresses() external view returns (address[] memory facetAddresses_);
        /// @notice Gets the facet that supports the given selector.
        /// @dev If facet is not found return address(0).
        /// @param _functionSelector The function selector.
        /// @return facetAddress_ The facet address.
        function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    interface IERC165 {
        /// @notice Query if a contract implements an interface
        /// @param interfaceId The interface identifier, as specified in ERC-165
        /// @dev Interface identification is specified in ERC-165. This function
        ///  uses less than 30,000 gas.
        /// @return `true` if the contract implements `interfaceID` and
        ///  `interfaceID` is not 0xffffffff, `false` otherwise
        function supportsInterface(bytes4 interfaceId) external view returns (bool);
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @title ERC-173 Contract Ownership Standard
    ///  Note: the ERC-165 identifier for this interface is 0x7f5828d0
    /* is ERC165 */
    interface IERC173 {
        /// @dev This emits when ownership of a contract changes.
        //event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
        /// @notice Get the address of the owner
        /// @return owner_ The address of the owner.
        function owner() external view returns (address owner_);
        /// @notice Set the address of the new owner of the contract
        /// @dev Set _newOwner to address(0) to renounce any ownership.
        /// @param _newOwner The address of the new owner of the contract
        function transferOwnership(address _newOwner) external;
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    interface IERC20 {
        function name() external view returns (string memory);
        function symbol() external view returns (string memory);
        function decimals() external view returns (uint8);
        function totalSupply() external view returns (uint256);
        function balanceOf(address _owner) external view returns (uint256 balance);
        function transferFrom(
            address _from,
            address _to,
            uint256 _value
        ) external returns (bool success);
        function transfer(address _to, uint256 _value) external returns (bool success);
        function approve(address _spender, uint256 _value) external returns (bool success);
        function allowance(address _owner, address _spender) external view returns (uint256 remaining);
        event Transfer(address indexed from, address indexed to, uint256 value);
        event Approval(address indexed owner, address indexed spender, uint256 value);
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import { IPresale} from "./IPresale.sol";
    interface INewToken {
        struct InitParams {
            address owner;
            address taxWallet;
            address stakingFacet;
            address v2router;
            bool isFreeTier;
            uint256 minLiq; 
            uint256 supply;
            uint256 initTaxType; //0-time,1-buyCount,2-hybrid
            uint256 initInterval; //seconds 0-1 hour(if 1m: 1m, 3m, 6m, 10m)
            uint256 countInterval; //0-100 
            uint256  maxBuyTax; //40%
            uint256  minBuyTax; //0
            uint256  maxSellTax; //40%
            uint256  minSellTax; //0
            uint256  lpTax; //0-90 of buy or sell tax
            uint256 maxWallet;
            uint256 maxTx;
            uint256 preventSwap;
            uint256 maxSwap;
            uint256 taxSwapThreshold;
            string  name;
            string  symbol;
        }
        
        struct TeamParams {
            address team1;
            uint256 team1p; 
            uint256 cliffPeriod; 
            uint256 vestingPeriod;
            bool isAdd;
        }
    \tfunction rescueERC20(address _address) external;
    \tfunction increaseLimits(uint256 maxwallet, uint256 maxtx) external;
    \tfunction startTrading(uint256 lockPeriod, bool shouldBurn, address router) external;
        //require trading and presale not started
        function addPresale(address presale, uint256 percent, IPresale.PresaleParams memory newdetails) external;
        //require caller to be presale address
        function finPresale() external;
        function refPresale() external;
        //requires presale not started and trading not started
        function addTeam(TeamParams memory params) external;
        //what if we remove team out from init?
    }
    interface IUniswapV2Factory {
        function createPair(address tokenA, address tokenB) external returns (address pair);
    }
    interface IUniswapV2Router02 {
        function swapExactTokensForETHSupportingFeeOnTransferTokens(
            uint amountIn,
            uint amountOutMin,
            address[] calldata path,
            address to,
            uint deadline
        ) external;
        function factory() external pure returns (address);
        function WETH() external pure returns (address);
        function addLiquidityETH(
            address token,
            uint amountTokenDesired,
            uint amountTokenMin,
            uint amountETHMin,
            address to,
            uint deadline
        ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    interface IPresale {
        struct PresaleParams {
                address owner;
                address token;
                uint256 softcap;
                uint256 hardcap;
                uint256 startTs;
                uint256 finishTs;
                uint256 duration;
                uint256 liqPercent;
                uint256 cliffPeriod;
                uint256 vestingPeriod;
                uint256 status;
                uint256 sold;
                uint256 maxEth;
                uint256 maxBag;
                uint256 fee;
        }
        function transferOwnership(address _newOwner) external;
        function owner() external view returns (address);
        function rescueERC20(address _address) external;
        function setupPresale(PresaleParams memory params) external;
        function buyTokens(uint256 _amount) external payable;
        //should we offer or force token vesting??
        function claimTokens() external;
        function getRefund() external;
        function getPresaleDetails() external view returns(PresaleParams memory); 
        function finishPresale() external; 
        function claimEth() external;
        function getClaimableTokens(address user) external view returns(uint256,uint256,uint256,uint256);
        function refundPresale() external;
    }
    // SPDX-License-Identifier: MIT
    /*********************************************************************************************\\
    * Deployyyyer: https://deployyyyer.io
    * Twitter: https://x.com/deployyyyer
    * Telegram: https://t.me/Deployyyyer
    /*********************************************************************************************/
    pragma solidity ^0.8.23;
    import {LibDiamond} from "./LibDiamond.sol";
    //import {LibMeta} from "./LibMeta.sol";
    import {IUniswapV2Factory, IUniswapV2Router02} from "../interfaces/INewToken.sol";
    struct AppStorage {
        mapping(address => bool) validRouters; //parentOnly
        mapping(address => bool) allowedTokens; //parentOnly
        //this should be bool too
        mapping(address => address) launchedTokens; //parentOnly
        mapping(address => address) launchedPresale; //parentOnly
        //cost of launch, cost of promo, cost of setting socials is 2xpromoCostEth
        uint256 ethCost; //parentOnly
        uint256 deployyyyerCost; //parentOnly
        uint256 promoCostEth; //parentOnly
        uint256 promoCostDeployyyyer; //parentOnly
        address bridge; //parentOnly
        //mapping of user address to score
        mapping(address => uint256) myScore; //parentOnly
        //+1 for launch, +5 for liquidity add, +50 for lp burn, -100 for lp retrieve
        uint256 cScore; //cScore is transferred with ownership, cScore is deducted on lp retrieve
        
        //address deployyyyer;
        bool isParent;
        uint256 minLiq;
        //this can be a map with share and clain in a structure
        mapping(address => uint256) teamShare;
        mapping(address => uint256) teamClaim;
        
        uint256 teamBalance;
        uint256 cliffPeriod; //min 30days
        uint256 vestingPeriod;//min 1day max 10000 days avg 30days.
        mapping(address => bool)  isExTxLimit; //is excluded from transaction limit
        mapping(address => bool)  isExWaLimit; //is excluded from wallet limit
        mapping (address => uint256)  balances; //ERC20 balance
        mapping (address => mapping (address => uint256))  allowances; //ERC20 balance
        address payable taxWallet; //tax wallet for the token
        address payable deployyyyerCa; //deployyyyer contract address
        address payable stakingContract; //address of staking contract for the token
        address stakingFacet; //facet address, used to launch a staking pool
        address presaleFacet; //facet address, used to launch a presale
        address tokenFacet; //facet address, used to launch a ERC20 token
        uint256 stakingShare; //share of tax sent to its staking pool
        
        
        // Reduction Rules
        uint256  buyCount; 
        uint256 initTaxType; //0-time,1-buyCount,2-hybrid,3-none
        //interval*1, lastIntEnd+(interval*2), lastIntEnd+(interval*3)
        uint256 initInterval; //seconds 0-1 hour(if 1m: 1m, 3m, 6m, 10m)
        uint256 countInterval; //0-100 
        //current taxes
        uint256  taxBuy; 
        uint256  maxBuyTax; //40%
        uint256  minBuyTax; //0
        uint256  taxSell; 
        uint256  maxSellTax; //40%
        uint256  minSellTax; //0
        
        
        uint256  tradingOpened;
        // Token Information
        uint8   decimals;
        uint256   tTotal;
        string   name;
        string   symbol;
        // Contract Swap Rules 
        uint256 preventSwap; //50            
        uint256  taxSwapThreshold; //0.1%
        uint256  maxTaxSwap; //1%
        uint256  maxWallet; //1%
        uint256  maxTx;
        IUniswapV2Router02  uniswapV2Router;
        address  uniswapV2Pair;
        
        bool  tradingOpen; //true if liquidity pool is created
        bool  inSwap;
        bool  walletLimited;
        bool isFreeTier;
        bool isBurnt;
        bool isRetrieved;
        uint256 lockPeriod;
        
        //buy back tax calculations
        uint256 lpTax; //0-50 percent of tax amount 
        uint256 halfLp;
        uint256 lastSwap;
        uint256 presaleTs;
        uint256 presaleSt;
        address presale;
    }
    /*
    library LibAppStorage {
        function diamondStorage() internal pure returns (AppStorage storage ds) {
            assembly {
                ds.slot := 0
            }
        }
        function abs(int256 x) internal pure returns (uint256) {
            return uint256(x >= 0 ? x : -x);
        }
    }
    */
    contract Modifiers {
        AppStorage internal s;
        modifier onlyOwner() {
            LibDiamond.enforceIsContractOwner();
            _;
        }  
        
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /*********************************************************************************************\\
    * Authors: Nick Mudge <[email protected]> (https://twitter.com/mudgen), 
    * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
    /*********************************************************************************************/
    import { IDiamondCut } from "../interfaces/IDiamondCut.sol";
    library LibDiamond {
        bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");
        struct DiamondStorage {
            // maps function selectors to the facets that execute the functions.
            // and maps the selectors to their position in the selectorSlots array.
            // func selector => address facet, selector position
            mapping(bytes4 => bytes32) facets;
            // array of slots of function selectors.
            // each slot holds 8 function selectors.
            mapping(uint256 => bytes32) selectorSlots;
            // The number of function selectors in selectorSlots
            uint16 selectorCount;
            // Used to query if a contract implements an interface.
            // Used to implement ERC-165.
            mapping(bytes4 => bool) supportedInterfaces;
            // owner of the contract
            address contractOwner;
        }
        function diamondStorage() internal pure returns (DiamondStorage storage ds) {
            bytes32 position = DIAMOND_STORAGE_POSITION;
            assembly {
                ds.slot := position
            }
        }
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
        function setContractOwner(address _newOwner) internal {
            DiamondStorage storage ds = diamondStorage();
            address previousOwner = ds.contractOwner;
            ds.contractOwner = _newOwner;
            emit OwnershipTransferred(previousOwner, _newOwner);
        }
        function contractOwner() internal view returns (address contractOwner_) {
            contractOwner_ = diamondStorage().contractOwner;
        }
        function enforceIsContractOwner() internal view {
            require(msg.sender == diamondStorage().contractOwner, "l0");
        }
        //event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
        //bytes32 constant CLEAR_ADDRESS_MASK = bytes32(uint256(0xffffffffffffffffffffffff));
        bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));
        // Internal function version of diamondCut
        // This code is almost the same as the external diamondCut,
        // except it is using 'Facet[] memory _diamondCut' instead of
        // 'Facet[] calldata _diamondCut'.
        // The code is duplicated to prevent copying calldata to memory which
        // causes an error for a two dimensional array.
        // also removed action on _calldata and _init is always address(0)
        // maintained same old signature
        function diamondCut(
            IDiamondCut.FacetCut[] memory _diamondCut,
            address _init,
            bytes memory _calldata
        ) internal {
            DiamondStorage storage ds = diamondStorage();
            uint256 originalSelectorCount = ds.selectorCount;
            uint256 selectorCount = originalSelectorCount;
            bytes32 selectorSlot;
            // Check if last selector slot is not full
            // "selectorCount & 7" is a gas efficient modulo by eight "selectorCount % 8" 
            if (selectorCount & 7 > 0) {
                // get last selectorSlot
                // "selectorSlot >> 3" is a gas efficient division by 8 "selectorSlot / 8"
                selectorSlot = ds.selectorSlots[selectorCount >> 3];
            }
            // loop through diamond cut
            for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
                (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(
                    selectorCount,
                    selectorSlot,
                    _diamondCut[facetIndex].facetAddress,
                    _diamondCut[facetIndex].action,
                    _diamondCut[facetIndex].functionSelectors
                );
            }
            if (selectorCount != originalSelectorCount) {
                ds.selectorCount = uint16(selectorCount);
            }
            // If last selector slot is not full
            // "selectorCount & 7" is a gas efficient modulo by eight "selectorCount % 8" 
            if (selectorCount & 7 > 0) {
                // "selectorSlot >> 3" is a gas efficient division by 8 "selectorSlot / 8"
                ds.selectorSlots[selectorCount >> 3] = selectorSlot;
            }
            //emit DiamondCut(_diamondCut, _init, _calldata);
            //initializeDiamondCut(_init, _calldata);
            require(_init == address(0), "l1");
            require(_calldata.length == 0, "l2");
        }
        //supports only add, maintaining lib fn name
        function addReplaceRemoveFacetSelectors(
            uint256 _selectorCount,
            bytes32 _selectorSlot,
            address _newFacetAddress,
            IDiamondCut.FacetCutAction _action,
            bytes4[] memory _selectors
        ) internal returns (uint256, bytes32) {
            DiamondStorage storage ds = diamondStorage();
            require(_selectors.length > 0, "l3");
            if (_action == IDiamondCut.FacetCutAction.Add) {
                enforceHasContractCode(_newFacetAddress, "l4");
                for (uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++) {
                    bytes4 selector = _selectors[selectorIndex];
                    bytes32 oldFacet = ds.facets[selector];
                    require(address(bytes20(oldFacet)) == address(0), "l5");
                    // add facet for selector
                    ds.facets[selector] = bytes20(_newFacetAddress) | bytes32(_selectorCount);
                    // "_selectorCount & 7" is a gas efficient modulo by eight "_selectorCount % 8" 
                    uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;
                    // clear selector position in slot and add selector
                    _selectorSlot = (_selectorSlot & ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) | (bytes32(selector) >> selectorInSlotPosition);
                    // if slot is full then write it to storage
                    if (selectorInSlotPosition == 224) {
                        // "_selectorSlot >> 3" is a gas efficient division by 8 "_selectorSlot / 8"
                        ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;
                        _selectorSlot = 0;
                    }
                    _selectorCount++;
                }
            } 
            else {
                revert("l6");
            }
            return (_selectorCount, _selectorSlot);
        }
        function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
            uint256 contractSize;
            assembly {
                contractSize := extcodesize(_contract)
            }
            require(contractSize > 0, _errorMessage);
        }
    }
    

    File 2 of 2: NewTokenFacet
    // SPDX-License-Identifier: MIT
    /*********************************************************************************************\\
    * Deployyyyer: https://deployyyyer.io
    * Twitter: https://x.com/deployyyyer
    * Telegram: https://t.me/Deployyyyer
    /*********************************************************************************************/
    pragma solidity ^0.8.23;
    import {Modifiers, AppStorage} from "../libraries/LibAppStorage.sol"; 
    import {LibDiamond} from "../libraries/LibDiamond.sol";
    import {IUniswapV2Factory, IUniswapV2Router02} from "../interfaces/INewToken.sol";
    import { INewToken } from "../interfaces/INewToken.sol";
    import { IERC20 } from "../interfaces/IERC20.sol";
    import { IHelper } from "../interfaces/IHelper.sol";
    import { IPresale } from "../interfaces/IPresale.sol";
    //import "hardhat/console.sol";
    library SafeCall {
        /**
         * @notice Perform a low level call without copying any returndata
         *
         * @param _target   Address to call
         * @param _gas      Amount of gas to pass to the call
         * @param _value    Amount of value to pass to the call
         * @param _calldata Calldata to pass to the call
         */
        function call(
            address _target,
            uint256 _gas,
            uint256 _value,
            bytes memory _calldata
        ) internal returns (bool) {
            bool _success;
            assembly {
                _success := call(
                    _gas, // gas
                    _target, // recipient
                    _value, // ether value
                    add(_calldata, 0x20), // inloc
                    mload(_calldata), // inlen
                    0, // outloc
                    0 // outlen
                )
            }
            return _success;
        }
    }
    /// @title NewTokenFacet 
    /// @notice Contains methods related to ERC20, starting and ending presales and setting team
    /// @dev 
    contract NewTokenFacet is IERC20, Modifiers {
        event TradingEnabled(address pair, uint256 liq, uint256 lockPeriod, bool isBurnt, address router);
    \tevent TaxMade(uint256 amount);
        event TaxGiven(uint256 amount);
        event IncreasedLimits(uint256 maxWallet, uint256 maxTx);
        event StakingMade(uint256 amount);
        event TeamSet(INewToken.TeamParams tparams);
        event PresaleAdded(address presaleId);
        event PresaleFinished(address presaleId);
        event PresaleRefunded(address presaleId);
        //reentrancy lock
        modifier lockTheSwap {
            s.inSwap = true;
            _;
            s.inSwap = false;
        }
        /// @notice Create liquidity pool and start trading for the token
        /// @dev
        function startTrading(uint256 lockPeriod, bool shouldBurn, address router) external payable onlyOwner {
            require(!s.tradingOpen && s.presaleSt != 1, "n1");
            require(address(this).balance >= s.minLiq, "n2");
            if(!shouldBurn) {
                require(lockPeriod >= 14);
            } else {
                s.cScore += 200;
            }
            
            s.cScore += 50; 
            s.tradingOpen = true;
            s.isExTxLimit[address(this)] = true;
            s.isExTxLimit[LibDiamond.contractOwner()] = true;
            s.isExTxLimit[address(s.uniswapV2Router)] = true;
            s.isExTxLimit[s.deployyyyerCa] = true;
            s.isExTxLimit[s.taxWallet] = true;
            s.isExWaLimit[address(this)] = true;
            s.isExWaLimit[LibDiamond.contractOwner()] = true;
            s.isExWaLimit[address(s.uniswapV2Router)] = true;
            s.isExWaLimit[s.deployyyyerCa] = true;
            s.isExWaLimit[s.taxWallet] = true;
            
            //0x000000000000000000000000000000000000dEaD or address(0)
            address liqOwner = address(this);
            if(shouldBurn) {
                liqOwner = address(0);
                s.isBurnt = true;
            } else {
                s.lockPeriod = lockPeriod;
                s.isBurnt = false;
            }
            uint256 liqBalance = s.balances[address(this)] - s.teamBalance;
            s.tradingOpened = block.timestamp;
            if(!s.isParent) {
                require(IHelper(s.deployyyyerCa).isValidRouter(router));
                s.uniswapV2Router = IUniswapV2Router02(router);
                s.allowances[address(this)][address(s.uniswapV2Router)] = s.tTotal;
            }
            s.uniswapV2Pair = IUniswapV2Factory(s.uniswapV2Router.factory()).createPair(address(this), s.uniswapV2Router.WETH());
            s.isExWaLimit[address(s.uniswapV2Pair)] = true;
            emit TradingEnabled(s.uniswapV2Pair, address(this).balance, lockPeriod, shouldBurn, router);
            require(IERC20(s.uniswapV2Pair).approve(address(s.uniswapV2Router), type(uint).max), "n3");
            //console.log(s.uniswapV2Router);
            s.uniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this),liqBalance,0,0,liqOwner,block.timestamp+60);
            if(!s.isParent)
                IHelper(s.deployyyyerCa).addScore(msg.sender, s.cScore);
            
            
        }
        /// @notice add a presale by calling setupPresale on presale contract launched by user
        /// @dev
        function addPresale(address presale, uint256 percent, IPresale.PresaleParams memory newdetails) external onlyOwner {
            require(s.presale == address(0) && !s.tradingOpen, "n4");
            //helperfacet isValidPresale if presale was launched by deployyyyer
            require(IHelper(s.deployyyyerCa).isValidPresale(presale), "n5");
            
            //check that the presale is not init with some other token
            IPresale.PresaleParams memory details = IPresale(presale).getPresaleDetails();
            require(details.owner == msg.sender, "n6");
            require(details.status == 0, "n7");
            require(details.token == address(this), "n77");
            s.presale = presale;
            s.presaleSt = 1;
            //transfer to presale contract.
            require(percent >= 100 && percent <= 2000, "n8");
            s.balances[presale] = s.tTotal*percent/10000;
            s.balances[address(this)] -= s.balances[presale];
            //add presale contract to txlimit
            //console.log(s.balances[presale]);
            s.isExTxLimit[presale] = true;
            s.isExWaLimit[presale] = true;
            //setup presale contract 
            newdetails.fee = 0;
            if(s.isFreeTier)  
                newdetails.fee = 5;
            newdetails.owner = msg.sender;
            newdetails.token = address(this);
            newdetails.softcap = s.balances[presale] * 25 / 100;
            newdetails.hardcap = s.balances[presale];
            
            require(newdetails.duration >= 1 && newdetails.duration <= 30, "n8");
            require(newdetails.liqPercent >= 80 &&  newdetails.liqPercent <= 100, "n9"); 
            require(newdetails.cliffPeriod >= 1 && newdetails.cliffPeriod <= 30, "n10");
            require(newdetails.vestingPeriod >= 7 && newdetails.vestingPeriod <= 30, "n11");
            newdetails.status = 1;
            newdetails.sold = 0;
            require(newdetails.maxEth > 0, "n12");
            require(newdetails.maxBag > 0 && newdetails.maxBag <= s.balances[presale]/10, "n13");
            
            emit Transfer(address(this), presale, s.balances[presale]);
            //we could emit extra details from presale instead of here
            emit PresaleAdded(presale);
            
            IPresale(presale).setupPresale(newdetails);
            
        }
        
        /// @notice finish presale
        /// @dev require caller to be its presale address
        function finPresale() external {
            require(msg.sender == s.presale, "n14");
            s.presaleSt = 2;
            emit PresaleFinished(s.presale);
        }
        /// @notice finish presale
        /// @dev require caller to be its presale address
        function refPresale() external {
            require(!s.tradingOpen, "n15");
            require(msg.sender == s.presale, "n16");
            emit PresaleRefunded(s.presale);
            //always reverts on error?
            require(address(this).balance > 0, "n17");
            payable(s.presale).transfer(address(this).balance);
        }
        /// @notice finish presale
        /// @dev require caller to be its presale address
        function addTeam(INewToken.TeamParams memory params) external onlyOwner {
            require(!s.tradingOpen && s.presaleSt == 0);
            if(s.cliffPeriod == 0 || params.cliffPeriod > 0) {
                require(params.cliffPeriod >= 0 && params.cliffPeriod <= 10000, "n19");
                s.cliffPeriod = params.cliffPeriod;
            }
            if(s.vestingPeriod == 0 || params.vestingPeriod > 0) {
                require(params.vestingPeriod >= 0 && params.vestingPeriod <= 10000, "n20");
                s.vestingPeriod = params.vestingPeriod;
            }
            //20% of supply
            if(params.isAdd) {
                s.teamShare[params.team1] += s.tTotal * params.team1p / 10000;
                s.teamBalance += s.tTotal * params.team1p / 10000;
                
            } else {
                //todo: what if sub goes below zero, crash or sets to zero
                s.teamShare[params.team1] -= s.tTotal * params.team1p / 10000;
                s.teamBalance -= s.tTotal * params.team1p / 10000;
            }
            require(s.teamBalance <= (s.tTotal*20/100), "n21");
            emit TeamSet(params);
            
        }
        /// @notice finish presale
        /// @dev require caller to be its presale address
        function increaseLimits(uint256 maxwallet, uint256 maxtx) external onlyOwner {
            require(s.walletLimited);
            require(s.tTotal * maxwallet / 100 >= s.maxWallet && maxwallet <= 100, "n23");
            require(s.tTotal * maxtx / 100 >= s.maxTx && maxtx <= 100, "n24");
            s.maxWallet =  s.tTotal * maxwallet / 100;   
            s.maxTx = s.tTotal * maxtx / 100;
            
            if (maxwallet == 100 && maxtx == 100) {
                s.walletLimited = false;
            }
            emit IncreasedLimits(maxwallet, maxtx);
        }
        ///@dev Returns the name of the token.
        function name() external view override returns (string memory) {
            return s.name;
        }
        ///@dev Returns the symbol of the token, usually a shorter version of name.
        function symbol() external view override returns (string memory) {
            return s.symbol;
        }
        ///@dev Returns the number of decimals used to get its user representation.
        function decimals() external view override returns (uint8) {
            return s.decimals;
        }
        ///@dev Returns the value of tokens in existence.
        function totalSupply() public view override returns (uint256) {
            return s.tTotal;
        }
        ///@dev Returns the value of tokens owned by account.
        function balanceOf(address account) public view override returns (uint256) {
            return s.balances[account];
        }
        ///@dev Moves a amount of tokens from the caller's account to receipient.
        function transfer(address recipient, uint256 amount) external override returns (bool) {
            _transfer(msg.sender, recipient, amount);
            return true;
        }
        ///@dev Returns the remaining number of tokens that `spender` will be
        // allowed to spend on behalf of `owner` through {transferFrom}. This is
        // zero by default
        function allowance(address owner, address spender) external view override returns (uint256) {
            return s.allowances[owner][spender];
        }
        /**
         * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
         * caller's tokens.
         *
         * Returns a boolean value indicating whether the operation succeeded.
         *
         * IMPORTANT: Beware that changing an allowance with this method brings the risk
         * that someone may use both the old and the new allowance by unfortunate
         * transaction ordering. One possible solution to mitigate this race
         * condition is to first reduce the spender's allowance to 0 and set the
         * desired value afterwards:
         * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
         *
         * Emits an {Approval} event.
         */
        function approve(address spender, uint256 amount) external override returns (bool) {
            _approve(msg.sender, spender, amount);
            return true;
        }
        /**
         * @dev Moves a `value` amount of tokens from `from` to `to` using the
         * allowance mechanism. `value` 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) public override returns (bool) {
            require(amount <= s.allowances[sender][msg.sender], "n25");
            _approve(sender, msg.sender, s.allowances[sender][msg.sender] - amount);
            _transfer(sender, recipient, amount);
            return true;
        }
        
        function _approve(address owner, address spender, uint256 amount) private {
            require(owner != address(0));
            require(spender != address(0));
            s.allowances[owner][spender] = amount;
            emit Approval(owner, spender, amount);
        }
        /// @notice sets tax for the trade
        /// @dev 
        function _setTax(bool isBuy) private {
            uint256 maxTax;
            uint256 minTax;
            uint256 tax;
            if(isBuy) {
                maxTax = s.maxBuyTax;
                minTax = s.minBuyTax;
                tax = s.taxBuy;
            } else {
                maxTax = s.maxSellTax;
                minTax = s.minSellTax;
                tax = s.taxSell;
            }
            if(tax != minTax) {
                if(s.initTaxType == 0) {
                    if (block.timestamp >= (s.tradingOpened + (s.initInterval))) {
                        tax = minTax; 
                    }
                    else if (block.timestamp >= (s.tradingOpened + (s.initInterval/2))) {
                        tax = minTax + (maxTax - minTax)/4;
                    }
                    else if (block.timestamp >= (s.tradingOpened + (s.initInterval/4))) {
                        //todo: verify multiply before divide
                        tax = minTax + ((maxTax - minTax)/2);
                    }
                    else {       
                        tax = maxTax; 
                    }        
                      
                } else if(s.initTaxType == 1) {
                    if (s.buyCount > (s.countInterval)) {
                        tax = minTax; 
                    } else {       
                        tax = maxTax; 
                    } 
                    //this is forced after 2hrs
                    if(block.timestamp >= (s.tradingOpened + 7200)) {
                        tax = minTax;
                    }      
                } else if(s.initTaxType == 2){
                    if (s.buyCount > (s.countInterval) || block.timestamp >= (s.tradingOpened + (s.initInterval))) {
                        tax = minTax; 
                    }
                    else if (s.buyCount > (s.countInterval/2) || block.timestamp >= (s.tradingOpened + (s.initInterval/2))) {
                        tax = minTax + (maxTax - minTax)/4;
                    }
                    else if (s.buyCount > (s.countInterval/4) || block.timestamp >= (s.tradingOpened + (s.initInterval/4))) {
                        //todo: verify multiply before divide
                        tax = minTax + ((maxTax - minTax)/2);
                    }
                    else {       
                        tax = maxTax; 
                    }        
                // } else if(s.initTaxType == 3) { //check block number}        
                    
                } else {
                    tax = minTax; 
                }
                if(isBuy) {
                    s.taxBuy = tax;
                } else {
                    s.taxSell = tax;
                }
            }
        }
        /// @notice internal method of transfer
        /// @dev 
        function _transfer(address from, address to, uint256 amount) private {
            require(from != address(0));
            require(to != address(0));
            //require(amount > 0); //compliance erc20
            require(s.balances[from] >= amount, "n66");
            uint256 taxAmount=0;
            
            if (s.tradingOpen && s.walletLimited && !s.isExTxLimit[from] && !s.isExTxLimit[to])
                require(s.maxTx >= amount, "n30");
            if (s.tradingOpen && s.walletLimited && !s.isExWaLimit[to])
                require((s.balances[to] + amount) <= s.maxWallet, "n31");
             
            if (from != LibDiamond.contractOwner() && to != LibDiamond.contractOwner()) {
                if (from == s.uniswapV2Pair && to != address(s.uniswapV2Router)) {
                \t//buy from uniswap, only if amount > 0
                    s.buyCount++;
                    _setTax(true);
                \ttaxAmount = amount * s.taxBuy / 100;
                    //console.log("_setTaxDone");
                    
                    
                }
                if(to == s.uniswapV2Pair && from!= address(this)) {
                \t//sell from uniswap
                    //max trans for sell?
                    _setTax(false);
                    taxAmount = amount * s.taxSell / 100;    
                }
            }
            uint256 contractTokenBalance = balanceOf(address(this)) - s.teamBalance;
            bool swapped = false;
            if (!s.inSwap && to == s.uniswapV2Pair && from!= address(this) && contractTokenBalance > s.taxSwapThreshold && s.buyCount > s.preventSwap) {
                    //we swap only on sell to uniswap pool
                    swapTokensForEth(min(contractTokenBalance, s.maxTaxSwap));
                    sendETHToFee(address(this).balance);
                    swapped = true;
            }
            if(taxAmount > 0) {
              s.balances[address(this)] = s.balances[address(this)] + (taxAmount);
              emit Transfer(from, address(this), taxAmount);
            }
            //from can be taxWallet
            s.balances[from] = s.balances[from] - amount;
            s.balances[to] = s.balances[to] + amount - taxAmount;
            emit Transfer(from, to, amount - taxAmount);
            
            if(swapped) {
                //everything else is taken care, anything left is for token's tax wallet
                //this call needs to be safe from reverts, consuming all gas and return bombs
                bool ttax = SafeCall.call(s.taxWallet, 100000, address(this).balance, "");
                if(ttax)
                    emit TaxMade(address(this).balance);
            }
        }
        /// @notice returns min of a and b
        function min(uint256 a, uint256 b) private pure returns (uint256){
          return (a>b)?b:a;
        }
        /// @notice swaps tokens from tax into eth
        /// @dev this is nonrentrant using lockTheSwap
        function swapTokensForEth(uint256 tokenAmount) private lockTheSwap {
            address[] memory path = new address[](2);
            //todo: will this work on pairs where 0 is weth?
            path[0] = address(this);
            path[1] = s.uniswapV2Router.WETH();
            
            if(s.lpTax > 0) { 
                s.halfLp = tokenAmount * s.lpTax / 200;  
                tokenAmount -= s.halfLp; 
                s.lastSwap = tokenAmount;
            }
            _approve(address(this), address(s.uniswapV2Router), tokenAmount);
            s.uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
                tokenAmount,
                0,
                path,
                address(this),
                block.timestamp
            );
        }
        /// @notice sends the eth to respective tax wallets and adds lp if token has buyback tax 
        /// @dev 
        function sendETHToFee(uint256 amount) private {  
            uint256 da = 0;
            uint256 ethLpShare = 0;
            uint256 stakingShare = 0;
            uint256 halfLpTemp;
            if(s.isFreeTier && ((block.timestamp - s.tradingOpened) < (86400*90))) {     
                //we take tax only for 3 month
                //this charge is taken for recovery function too!
                da = amount * 10 / 100;
                emit TaxGiven(da);
                (bool stax, ) = s.deployyyyerCa.call{value: da}("");
                require(stax, "ns99");
            }
            if(s.lpTax > 0 && s.halfLp > 0) {
                //newly added liquidity is also locked
                //address liqOwner = address(this);
                
                //we should also be keeping half of lp in tokens, so that u add equal amount of eth and token to lp
                ethLpShare = s.halfLp * amount / s.lastSwap;
                halfLpTemp = s.halfLp;
                s.halfLp = 0;
                s.lastSwap = 0;
                _approve(address(this), address(s.uniswapV2Router), halfLpTemp);
                s.uniswapV2Router.addLiquidityETH{ value: ethLpShare }(
                    address(this),
                    halfLpTemp,
                    0,
                    0,
                    address(this),
                    block.timestamp + 60
                );
                
            }
            if(s.stakingContract != address(0)) {
                stakingShare = (amount - da - ethLpShare) * s.stakingShare / 100;
                //todo: is 2300 gas sufficient 
                //stakingContract is safe since its our own! 
                (bool sent, ) = s.stakingContract.call{value: stakingShare}("");
                require(sent, "ns9");
                emit StakingMade(stakingShare);
            }
            
        }
        /// @notice recovers eth to tax wallet if any
        /// @dev 
        function recoverEth() private {
            //blocked while trading is disabled
            if(!s.inSwap && s.tradingOpen) { 
                uint256 contractETHBalance = address(this).balance;
                if(contractETHBalance > 0) {
                    sendETHToFee(contractETHBalance);
                    (bool ttax, ) = s.taxWallet.call{value: address(this).balance}("");
                    if(ttax)
                        emit TaxMade(address(this).balance);
                }
            }
        }
        /// @notice rescues any erc20 tokens sent to contract, also recovers eth to tax wallet if any
        /// @dev trying to rescue own token or own lp tokens will revert
        function rescueERC20(address _address) external {
            //block pulling out lp
            require(_address != s.uniswapV2Pair); 
            //block team token share
            require(_address != address(this));
            
            require(IERC20(_address).transfer(s.taxWallet, IERC20(_address).balanceOf(address(this))), "n32");
            recoverEth();
        }
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /******************************************************************************\\
    * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
    * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
    /******************************************************************************/
    interface IDiamondCut {
        enum FacetCutAction {Add, Replace, Remove}
        // Add=0, Replace=1, Remove=2
        struct FacetCut {
            address facetAddress;
            FacetCutAction action;
            bytes4[] functionSelectors;
        }
        /// @notice Add/replace/remove any number of functions and optionally execute
        ///         a function with delegatecall
        /// @param _diamondCut Contains the facet addresses and function selectors
        /// @param _init The address of the contract or facet to execute _calldata
        /// @param _calldata A function call, including function selector and arguments
        ///                  _calldata is executed with delegatecall on _init
        function diamondCut(
            FacetCut[] calldata _diamondCut,
            address _init,
            bytes calldata _calldata
        ) external;
        event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    interface IERC20 {
        function name() external view returns (string memory);
        function symbol() external view returns (string memory);
        function decimals() external view returns (uint8);
        function totalSupply() external view returns (uint256);
        function balanceOf(address _owner) external view returns (uint256 balance);
        function transferFrom(
            address _from,
            address _to,
            uint256 _value
        ) external returns (bool success);
        function transfer(address _to, uint256 _value) external returns (bool success);
        function approve(address _spender, uint256 _value) external returns (bool success);
        function allowance(address _owner, address _spender) external view returns (uint256 remaining);
        event Transfer(address indexed from, address indexed to, uint256 value);
        event Approval(address indexed owner, address indexed spender, uint256 value);
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    interface IHelper {
    \tstruct LauncherDetails {
    \tuint256 ethCost; 
    \tuint256 deployyyyerCost; 
    \tuint256 promoCostEth; 
    \tuint256 promoCostDeployyyyer; 
    \tuint256 minLiq; 
    \taddress bridge;
    \t}
    \tfunction addScore(address owner, uint256 score) external;
    \tfunction transferScore(address owner, address newOwner, uint256 score) external;
    \tfunction punishScore(address owner, uint256 score) external;
    \tfunction isValidPresale(address presale) external view returns (bool);
    \tfunction isValidRouter(address router) external view returns (bool);
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import { IPresale} from "./IPresale.sol";
    interface INewToken {
        struct InitParams {
            address owner;
            address taxWallet;
            address stakingFacet;
            address v2router;
            bool isFreeTier;
            uint256 minLiq; 
            uint256 supply;
            uint256 initTaxType; //0-time,1-buyCount,2-hybrid
            uint256 initInterval; //seconds 0-1 hour(if 1m: 1m, 3m, 6m, 10m)
            uint256 countInterval; //0-100 
            uint256  maxBuyTax; //40%
            uint256  minBuyTax; //0
            uint256  maxSellTax; //40%
            uint256  minSellTax; //0
            uint256  lpTax; //0-90 of buy or sell tax
            uint256 maxWallet;
            uint256 maxTx;
            uint256 preventSwap;
            uint256 maxSwap;
            uint256 taxSwapThreshold;
            string  name;
            string  symbol;
        }
        
        struct TeamParams {
            address team1;
            uint256 team1p; 
            uint256 cliffPeriod; 
            uint256 vestingPeriod;
            bool isAdd;
        }
    \tfunction rescueERC20(address _address) external;
    \tfunction increaseLimits(uint256 maxwallet, uint256 maxtx) external;
    \tfunction startTrading(uint256 lockPeriod, bool shouldBurn, address router) external;
        //require trading and presale not started
        function addPresale(address presale, uint256 percent, IPresale.PresaleParams memory newdetails) external;
        //require caller to be presale address
        function finPresale() external;
        function refPresale() external;
        //requires presale not started and trading not started
        function addTeam(TeamParams memory params) external;
        //what if we remove team out from init?
    }
    interface IUniswapV2Factory {
        function createPair(address tokenA, address tokenB) external returns (address pair);
    }
    interface IUniswapV2Router02 {
        function swapExactTokensForETHSupportingFeeOnTransferTokens(
            uint amountIn,
            uint amountOutMin,
            address[] calldata path,
            address to,
            uint deadline
        ) external;
        function factory() external pure returns (address);
        function WETH() external pure returns (address);
        function addLiquidityETH(
            address token,
            uint amountTokenDesired,
            uint amountTokenMin,
            uint amountETHMin,
            address to,
            uint deadline
        ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    interface IPresale {
        struct PresaleParams {
                address owner;
                address token;
                uint256 softcap;
                uint256 hardcap;
                uint256 startTs;
                uint256 finishTs;
                uint256 duration;
                uint256 liqPercent;
                uint256 cliffPeriod;
                uint256 vestingPeriod;
                uint256 status;
                uint256 sold;
                uint256 maxEth;
                uint256 maxBag;
                uint256 fee;
        }
        function transferOwnership(address _newOwner) external;
        function owner() external view returns (address);
        function rescueERC20(address _address) external;
        function setupPresale(PresaleParams memory params) external;
        function buyTokens(uint256 _amount) external payable;
        //should we offer or force token vesting??
        function claimTokens() external;
        function getRefund() external;
        function getPresaleDetails() external view returns(PresaleParams memory); 
        function finishPresale() external; 
        function claimEth() external;
        function getClaimableTokens(address user) external view returns(uint256,uint256,uint256,uint256);
        function refundPresale() external;
    }
    // SPDX-License-Identifier: MIT
    /*********************************************************************************************\\
    * Deployyyyer: https://deployyyyer.io
    * Twitter: https://x.com/deployyyyer
    * Telegram: https://t.me/Deployyyyer
    /*********************************************************************************************/
    pragma solidity ^0.8.23;
    import {LibDiamond} from "./LibDiamond.sol";
    //import {LibMeta} from "./LibMeta.sol";
    import {IUniswapV2Factory, IUniswapV2Router02} from "../interfaces/INewToken.sol";
    struct AppStorage {
        mapping(address => bool) validRouters; //parentOnly
        mapping(address => bool) allowedTokens; //parentOnly
        //this should be bool too
        mapping(address => address) launchedTokens; //parentOnly
        mapping(address => address) launchedPresale; //parentOnly
        //cost of launch, cost of promo, cost of setting socials is 2xpromoCostEth
        uint256 ethCost; //parentOnly
        uint256 deployyyyerCost; //parentOnly
        uint256 promoCostEth; //parentOnly
        uint256 promoCostDeployyyyer; //parentOnly
        address bridge; //parentOnly
        //mapping of user address to score
        mapping(address => uint256) myScore; //parentOnly
        //+1 for launch, +5 for liquidity add, +50 for lp burn, -100 for lp retrieve
        uint256 cScore; //cScore is transferred with ownership, cScore is deducted on lp retrieve
        
        //address deployyyyer;
        bool isParent;
        uint256 minLiq;
        //this can be a map with share and clain in a structure
        mapping(address => uint256) teamShare;
        mapping(address => uint256) teamClaim;
        
        uint256 teamBalance;
        uint256 cliffPeriod; //min 30days
        uint256 vestingPeriod;//min 1day max 10000 days avg 30days.
        mapping(address => bool)  isExTxLimit; //is excluded from transaction limit
        mapping(address => bool)  isExWaLimit; //is excluded from wallet limit
        mapping (address => uint256)  balances; //ERC20 balance
        mapping (address => mapping (address => uint256))  allowances; //ERC20 balance
        address payable taxWallet; //tax wallet for the token
        address payable deployyyyerCa; //deployyyyer contract address
        address payable stakingContract; //address of staking contract for the token
        address stakingFacet; //facet address, used to launch a staking pool
        address presaleFacet; //facet address, used to launch a presale
        address tokenFacet; //facet address, used to launch a ERC20 token
        uint256 stakingShare; //share of tax sent to its staking pool
        
        
        // Reduction Rules
        uint256  buyCount; 
        uint256 initTaxType; //0-time,1-buyCount,2-hybrid,3-none
        //interval*1, lastIntEnd+(interval*2), lastIntEnd+(interval*3)
        uint256 initInterval; //seconds 0-1 hour(if 1m: 1m, 3m, 6m, 10m)
        uint256 countInterval; //0-100 
        //current taxes
        uint256  taxBuy; 
        uint256  maxBuyTax; //40%
        uint256  minBuyTax; //0
        uint256  taxSell; 
        uint256  maxSellTax; //40%
        uint256  minSellTax; //0
        
        
        uint256  tradingOpened;
        // Token Information
        uint8   decimals;
        uint256   tTotal;
        string   name;
        string   symbol;
        // Contract Swap Rules 
        uint256 preventSwap; //50            
        uint256  taxSwapThreshold; //0.1%
        uint256  maxTaxSwap; //1%
        uint256  maxWallet; //1%
        uint256  maxTx;
        IUniswapV2Router02  uniswapV2Router;
        address  uniswapV2Pair;
        
        bool  tradingOpen; //true if liquidity pool is created
        bool  inSwap;
        bool  walletLimited;
        bool isFreeTier;
        bool isBurnt;
        bool isRetrieved;
        uint256 lockPeriod;
        
        //buy back tax calculations
        uint256 lpTax; //0-50 percent of tax amount 
        uint256 halfLp;
        uint256 lastSwap;
        uint256 presaleTs;
        uint256 presaleSt;
        address presale;
    }
    /*
    library LibAppStorage {
        function diamondStorage() internal pure returns (AppStorage storage ds) {
            assembly {
                ds.slot := 0
            }
        }
        function abs(int256 x) internal pure returns (uint256) {
            return uint256(x >= 0 ? x : -x);
        }
    }
    */
    contract Modifiers {
        AppStorage internal s;
        modifier onlyOwner() {
            LibDiamond.enforceIsContractOwner();
            _;
        }  
        
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /*********************************************************************************************\\
    * Authors: Nick Mudge <[email protected]> (https://twitter.com/mudgen), 
    * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
    /*********************************************************************************************/
    import { IDiamondCut } from "../interfaces/IDiamondCut.sol";
    library LibDiamond {
        bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");
        struct DiamondStorage {
            // maps function selectors to the facets that execute the functions.
            // and maps the selectors to their position in the selectorSlots array.
            // func selector => address facet, selector position
            mapping(bytes4 => bytes32) facets;
            // array of slots of function selectors.
            // each slot holds 8 function selectors.
            mapping(uint256 => bytes32) selectorSlots;
            // The number of function selectors in selectorSlots
            uint16 selectorCount;
            // Used to query if a contract implements an interface.
            // Used to implement ERC-165.
            mapping(bytes4 => bool) supportedInterfaces;
            // owner of the contract
            address contractOwner;
        }
        function diamondStorage() internal pure returns (DiamondStorage storage ds) {
            bytes32 position = DIAMOND_STORAGE_POSITION;
            assembly {
                ds.slot := position
            }
        }
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
        function setContractOwner(address _newOwner) internal {
            DiamondStorage storage ds = diamondStorage();
            address previousOwner = ds.contractOwner;
            ds.contractOwner = _newOwner;
            emit OwnershipTransferred(previousOwner, _newOwner);
        }
        function contractOwner() internal view returns (address contractOwner_) {
            contractOwner_ = diamondStorage().contractOwner;
        }
        function enforceIsContractOwner() internal view {
            require(msg.sender == diamondStorage().contractOwner, "l0");
        }
        //event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
        //bytes32 constant CLEAR_ADDRESS_MASK = bytes32(uint256(0xffffffffffffffffffffffff));
        bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));
        // Internal function version of diamondCut
        // This code is almost the same as the external diamondCut,
        // except it is using 'Facet[] memory _diamondCut' instead of
        // 'Facet[] calldata _diamondCut'.
        // The code is duplicated to prevent copying calldata to memory which
        // causes an error for a two dimensional array.
        // also removed action on _calldata and _init is always address(0)
        // maintained same old signature
        function diamondCut(
            IDiamondCut.FacetCut[] memory _diamondCut,
            address _init,
            bytes memory _calldata
        ) internal {
            DiamondStorage storage ds = diamondStorage();
            uint256 originalSelectorCount = ds.selectorCount;
            uint256 selectorCount = originalSelectorCount;
            bytes32 selectorSlot;
            // Check if last selector slot is not full
            // "selectorCount & 7" is a gas efficient modulo by eight "selectorCount % 8" 
            if (selectorCount & 7 > 0) {
                // get last selectorSlot
                // "selectorSlot >> 3" is a gas efficient division by 8 "selectorSlot / 8"
                selectorSlot = ds.selectorSlots[selectorCount >> 3];
            }
            // loop through diamond cut
            for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
                (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(
                    selectorCount,
                    selectorSlot,
                    _diamondCut[facetIndex].facetAddress,
                    _diamondCut[facetIndex].action,
                    _diamondCut[facetIndex].functionSelectors
                );
            }
            if (selectorCount != originalSelectorCount) {
                ds.selectorCount = uint16(selectorCount);
            }
            // If last selector slot is not full
            // "selectorCount & 7" is a gas efficient modulo by eight "selectorCount % 8" 
            if (selectorCount & 7 > 0) {
                // "selectorSlot >> 3" is a gas efficient division by 8 "selectorSlot / 8"
                ds.selectorSlots[selectorCount >> 3] = selectorSlot;
            }
            //emit DiamondCut(_diamondCut, _init, _calldata);
            //initializeDiamondCut(_init, _calldata);
            require(_init == address(0), "l1");
            require(_calldata.length == 0, "l2");
        }
        //supports only add, maintaining lib fn name
        function addReplaceRemoveFacetSelectors(
            uint256 _selectorCount,
            bytes32 _selectorSlot,
            address _newFacetAddress,
            IDiamondCut.FacetCutAction _action,
            bytes4[] memory _selectors
        ) internal returns (uint256, bytes32) {
            DiamondStorage storage ds = diamondStorage();
            require(_selectors.length > 0, "l3");
            if (_action == IDiamondCut.FacetCutAction.Add) {
                enforceHasContractCode(_newFacetAddress, "l4");
                for (uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++) {
                    bytes4 selector = _selectors[selectorIndex];
                    bytes32 oldFacet = ds.facets[selector];
                    require(address(bytes20(oldFacet)) == address(0), "l5");
                    // add facet for selector
                    ds.facets[selector] = bytes20(_newFacetAddress) | bytes32(_selectorCount);
                    // "_selectorCount & 7" is a gas efficient modulo by eight "_selectorCount % 8" 
                    uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;
                    // clear selector position in slot and add selector
                    _selectorSlot = (_selectorSlot & ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) | (bytes32(selector) >> selectorInSlotPosition);
                    // if slot is full then write it to storage
                    if (selectorInSlotPosition == 224) {
                        // "_selectorSlot >> 3" is a gas efficient division by 8 "_selectorSlot / 8"
                        ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;
                        _selectorSlot = 0;
                    }
                    _selectorCount++;
                }
            } 
            else {
                revert("l6");
            }
            return (_selectorCount, _selectorSlot);
        }
        function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
            uint256 contractSize;
            assembly {
                contractSize := extcodesize(_contract)
            }
            require(contractSize > 0, _errorMessage);
        }
    }