/**
Despite numerous efforts to uncover his identity, Nakamoto has proven elusive. 
Several individuals have been proposed but none have been proven to be Satoshi Nakamoto beyond a doubt.

Lets Spread The Word And Get Him Found And Turn This Bear Market Around!

50% OF ALL TAX WILL GO TO MAJOR MARKETING CAMPAIGNS SUCH AS BILLBOARDS,YAHOO FINANCE, TWITTER PUSH ETC.

https://t.me/SatoshisPortal
Website Released At 300k MC


                                                                                                                                                      
  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  . .  .  .
   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .  
     .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .     
 .  .    . .     .       . .     .       .       .       .       .       .       .       .       .       .       .       .       .       .       .  . 
   . . :;:. . ..  . . ...t. . . .  .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  .    .  
  . . XX. : .     .  .  X.S  ;S .   .   .   .   .   .   .   .   . . .  .  .    .  . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .     
    . : :%:X@SS8%8@S%8:;@ @8XS8 . .   .   .   .   .   .  . .  . .;%X8888@888888X%t%t::.  . . .    .   .   .   .   .   .   .   .   .   .   .   .   .  .
  . . .XX8t.; ; St X@ %8t  :.@% .       .       .    .   .;S88XttX88SSXXS%t;tSX%;:;SXS%%%%%t:.  .       .       .       .       .       .       .     
    . 8 X.XX;8:S@ @S 8t;:8;X 88  .  .      . .   . .. .S8@888@888SSS%%S%%t%tSXS%t%S@X%ttt..;%S%:  .. .     . .     . .     . .     . .     . .     .  
  . . . .  . ...  . ... . . . . . .   .  .     .  :S8@8@SS@@@88@XS%%%%t%%t%SS%t%%SSXSSXXSS;. .:;tS%;  .  .     .       .       .       .       .  .  .
       . .  . XX . . @S..   .  .    .   .  .. .;8%.tS8SSX@@8888@SS%%%%%tt%%%%%%S%SSSSXS%%XXS;..;t;.t@XS.  . .    . .     . .     . .     . .          
  .  .    . 8%;;%@.@:8 ;t:       .    .   .  ;8S@8@88@@@8@88888@XS%SS%t%t%%%%SS%S%%XSS%SXXXSS%SXXS%t:t8XX .. .       . .     . .     . .     . . .  . 
    .   . . S@ .88 t%8S@t. . .  .  .   .  .X8888888888@@X@888@@@SSX88XSX%%S%%S%SSSSSS%SSXSSSS%%%SSS%%%%S@88:. . . .      .       .       .         .  
  .   .    .@; .tS:8X% t::     .     .. %88@@8888888@XXS@8888@%.@8%..... .:.8@X%%SSSSSXSSS%%%SSS%%t%SS%SXSS88%.     .  .   . .     . .     . .  .     
         .  . X8 . . t8 . .  .    .  . 8t%%@888888@X@XSSX@8.t:8St@@8X88@S8X:t:t8XXXSSXSXSS8@@XXStt%%%tSXS%%%%88: .    .        .  .    .  .       .  .
  . . ..  . ..     .  . .  . .  .  . %8X;S@88888@@@@SXS%St%%t8%tXX88X8SSS;::.;X@.@@8888888X8@@88@%%%%SS%S%SSXSS8X...    . .  .   .   .   .   . .   .  
    .8:;X..88 %...  . . . . @@ . ..%XX;%XX88@888@@XSS%@:8@:@8888888X%%%:tX;tS;;tX%S8888XSS% 8S@X8%8%SSSSSSXSSX@XSS%. .         .       .         .    
  .. Xt;8 tX:St;;.tX;;:%;X;S@ tX  X%;;%X@88@@@@8@@@S%@X 8;%8@X.S8;.%. @88@@.SS%;;88%S% 8%Xt@8;X88  8XXSSSXS@@XS%%;;S. ..  . .     . .     . .  .    . 
   ..:8 : t;.   SS88S8@X% %% 8S  88tt%@@88@88@@@SX%X. S8;t@88X888@@888t.t8S;X;@X8@ttt88 X.8@@t%@S%S 8%SSSSSXSSS%;...;:  .     .  .    .  .        .   
  . @; @..t;S8.S;8;@%;t@ .:S S@88%;%S@8@@@888@@XSt88; :X 8@S:8S@;..;SS@8Xt;t8;8 t .    8% SX t8@t:8@@;XSXXSSSSX@%:.::;t.  .    .    .       . . .    .
         .    .  .  .   .  .  ;8;t%X@8@X@8888XSSt88@ . S;8;S :% .  . .@XX8.8@ t .  .   tS . @Xt%@.t;StXSSSXSXXX%S%tSS;%X .  .     .   . .         .   
  . . . .  ... ::..  ... .. .t8ttSX88@XXSX@8@XS;88%t@@..;8t;:: %XX8.X%S8XX 8X: ..    . :8XX8;8 S%X%8 8 @XSSSSS%%%S%S%%:S8..  .  .         . .  .    . 
       .   . ; 8;;:S.;:;. . X8;%X88@8XS%t%S%%%:@ %t@:SXSS%%:;;88X8 @t  %8St;;;:. .    . 8%tt;tt.: ;;@:X SSSSS%%%%%tt;:. %8..      . .  .         .    
  .  .   . . @   @;X8X 8S  t@tS@@88@XS%t%SS%t;@tSt SXX8@S;:t @X XS8@tX88X%%ttt;.  . . :.88;X%S8.%@@@@Xt@8%%S%S%%tt;;;;.  tS   . .        .  . .    .  
    .      . X:.@ .@;@t ..:8S%@8888@S%t%S%%%;S%%% XX%%XSt;t S@.8@8%X888Stttt;:....:::::.tStXX%8X@;S X%@8 S.%%%ttt;;t%S;:. t; .     . . .        .    .
  .   . . . :X;; :8S.SX ..8X@8888@XSttXS%%;8S@ . 8S%XX;8t@ 88:X@8:S%@8XSSXX%t;;;::. .:;t:S@%XXX@8:@: @X@@8@8.;tt;t%%%%t:.::t; .  .       . .  .   .   
    .. .. .       .  ... @8X88888SSt;tSXt%S8t8S %:%8t.;8X 8S.t %@.X8X%tttt.  .  ..;tt; . 88tSX@S8@ t.8%@@88 %  ttt%%t;;%:SSt%.      .  .        .   . 
  .  tS@S: . ..  . .    :@88888@X%t;;;t;.t8 @X ;:.8:t%S::%  88%;::88XSS@@ttt;::;:::.. :@:;8t%S8XX@8t%8t:@SXXt.;;tttt;;;tS%Stt; . .        . . .       
    .;.S8:%8.;%88X%@t88%. . :X.@tt;;;:8.@.88@8..t%;.t::8 8t;.;S@;@XSt%Xt::. . .8S   .::S%.%;%@X@S: ;.X888X@XS% 8S;;;;;%%%tt%%t.    . .  .        . .  
  .  X;S ;%8  8X@88 S.X8%tXS: 8X.;;t.88;  X  8@8.X:@@@ 8.8%8S8%t ;@.XXt;;.. .;;S X@.:XS8:SX :%8S8tt.t;8@8@SXSX8S%:t;t%ttt%SS%%t .      .   .  .      .
   . X%: 8X :S:;tXXX%@%:%: 8@@X :;t:8%8.@SX .%X;S@888S8  :XX ;X;t.@.88@XS:;8tX.8S%@S%tt%%%S@;%S@SS.@8t 8;@S@SX@X@%tttt;t%%S%ttS: .  .    .      .  .  
  . ........ .... .. .:@888@X%t;;;;: S.:X8%8@ 8% tX%8 S% S@;8@X888@t:S@88@S8%XX:::t8X%X@@XtXSS;X8.;.t S;888@SX8t @;tttt%%ttt;tX@ .    .     . .       
      . .. .. ..   .  SX888Xttt;;;:@88@ ;X8X8 88..:S 8XS@tXS888@8XX@;S;88888%;.X8t@    ::S8@8t:S8 S.X;%t%88@%88: 8;tt%St;t;tt;SX. .  .   .      . . . 
  .              .  . 8S888tt;;;;t..8@StX8@8S:@ % S 88: :X8..%:t%.@8;8;@88@@X;8 ;%. ..     X:8%.@888%X.@t:::%S8S.8;t%tttt;tttt;:t .    .   .  .       
    . .  . . .     .  8@@@t;;;;;;t.;St.:%@.@@ Xt S;8X.S@%@@%88@:  .S. : 888@X.%S8: ;S@S@88888tX@S8888%8X;X:t8;%8  %tt;;;tttt;; ;8 .  .      .    .  . 
  .            . .   :88t;;;;;;t;;:S .SX:t8X8XSS8@:X8%;X X8X8SX%St;; :S%t888%SX;8%@  8:St  :8tX888@%S :% SSXX@8@S:tt;;;t;t;;t;.tS .     . .    .      
    .  .  .  .     . :8%:tt;tttt;;;:88%X ;t;%.8X88 @@8;S%;:::t;;t%X8t.888888;t@ %8:t88@St;@8@X@8:SX888 @:;;%;@ t;t;;;t;;;;;%XS XS . .  .     .    .  .
  .     .      .   . ;8XtStttt;;t;;.%:@.Xt8X:%.@8t@;:8. :.8.@8t@  %@88%  %..S:8 @%8XS%X@@@8X:;.:t%88%:t..StX. S;;;t;t;;;;t%%St:8% .       .     .     
     .    . .    .   t8@%S%tt;;;;;tt.  @ :@X t S8; 88S8SS%8X @XX 88X:8 :X.;;:;X@ t%.t8X@@.  S@  @;SS8 S8.:8  8:t;;;;;;;;t%ttS;.@8 .  .  .   . .   . . 
  .   .       .    . %X8S%t%;;t;;t;;.8t.:X%:X88;8@ Xt @S;%t8:.t%%X@t8%8SX;8. XtSX ;8t;:::t@8X:  :%St8..;.Xt8X:;;;t;;;;t%ttt;;;.88 .   .   .           
   .    .  .    .  . tX@%%t;;t;;;;;;t%X8SS .tX;.8.t t%@S@@;.t@%%%@t:SS8t.t:. X%8X:8:;.t.:.X%t ;;888%%X SX8.:;;t;;;;;ttt;t:;t%%:XS . .        .  . .  .
     .   .   .    .  :@%;t;tt;tt;;tt%%%:..S8%%@8. :t8:%::88S@8@t;XtX.@;@88 . t:8. : ;X8S t@  St8:8888% :.: ;;t;tt;ttt;;:;;;%%%;%X      . .     .      
 .  .  .       .    ..@S;;tttt;;;tt%%%%%%@X@@S X;; : t.%:;%t@;.t;.@8X%Xt;;. . %8 S8t8@SX@88S%8.8.88888 . 8.tt;t;;tt;;;;;;ttttt.tS .  .     .      . . 
          . .    . .  88;t%ttt;ttt%%%%%%%t;88S 8:8   X8@;;8S%;t%SX8:  X@8. . ..S8;8;;t%%%8X . :X;X@8@  ;88;tttttt;;;::;;;;;;;:t;: .    .    . .  .    
  .  .  .     .     . SX%%t%ttt;t%%%%%%%ttS@:8%; S 8  tX%8;S%.%X88:8:;8.8 . .   .  ;% ..  8t .St@X88 : tX%tt%ttt;;;;;;;;;;;;t;%. .  .    .          . 
   .      .    .  .   ;;8t%%ttt%%%%%%%%%%%XXXt  8% X  @@8;8;%XS;;S%X.X% 8t;.:.S  t8S;X   ..: : 88X@S  XS8.S%ttt;;:;;;t;;;:tt%;S8 .    .   .  . .  .   
 .   . .    .    .   . S%%t%%t%%%%%%%tt%%SS%t.8 . .@  SS%X8..ttt%tX:;88S8@8t.:.S;:8 8.%. . . 88@X%@@ tt%%;%tt;;;;;;;;;:;;%tt:@t.  . .   .        .   .
         .   .     .   S:S%%S%%%S%%t%%t%SSttt%.SS@ @  8  ;t.;tt%;8;8XX tX;@S%%St. .  t8:  .. ttSXX8;@tt  Stt;;::;;;;:;;;;t;t ;S .     .    .  .    .  
  . .  .   .   .     .. .Xt%%SS%%%%tttt%%%tt%X%S ;X S 8 %%%:t%%%%@XSX888X@. ;:. .. . .;8;. . @%8X@8@ 8X8.%;:::;;;;:;:;;;;;;:S:;.  .      .   .  .     
         .      . .    .t.@%S@X%%tt%%t%%ttt%SSS;t t.88@% .8;%%%%88% %8Xtt:%@S . ..    ..8; . X 88@S. .X.::::;;:;:;:;;;;;;;;; 8 .    .  .   .      .  .
  .  .      . .     .  . X.t@SXS%S%tt%tttt%S%%SX;. X.8. ;.8;S%S%%8tXS S8ttX%;%:@ .:.  . :X.  8 888X;tX.:::;;;:::;:;;;:;%;;;8: .  .   .   .    .       
    .  .  .      .    . ..;8X%SX%%tt%%t%tt%%%SSXX%  .S@88.%;SStt%8S88 t8;.XS     ;t%..;  :.. X:8@XSS% ::;;;;;:;:;;;:;:X%;%;tt      .        .   . . . 
  .     .    .  .  .   . .;SXSSSXtt%%%%%%%%SS%SXS8X@S X @X%XS;:;tS%8t.;%;8;;%ttX@S% X8 8... ..t%S88S:.;;;;;;;;;;;;:;:S%;t:8S.. . .    . .  .   .      
     .    .          .     SttS%%%%%SS%tt%%%SSSX@@XXSX8t 8@ .t88 ; :.:8X.8t .; XtX;X. . % . X %.XX@S8;t;t;;;;;;;;:::tttt;%X         .        .    .  .
  .    .    . .  .      . . 8 %St%SSX%%%%%%SSSX@XXS@@X X 88 8S@tXSSt...%.@ .  .@: ....  % ..XStt88SXtttt;;;;;t;;;;;tt%t%X8: .  .  .    . .      .     
    .    .      .  .  .    . S.S;tX@S%t%%%SXXXXXXXX@88X;8 88ttS8St%XStt8;: . :.%@X%tS;..X; 888t@S SS:%ttt;t;;;;;:tttt%S@8. .     .   .     .  .   .  .
  .   .    .  .     .   .   . %...:;SttS%S@@XX@XXXX@888.S. 8:8t8X%XS8:S8    .;;  8@8S;8%t :88%@@@%.St%ttt;;;:;;;t%%%Stt8 .   . .   .    .   .      .  
    .   .    .   .    .   .  . SX;. :SXSS@8XXXXXX@888888 8  S..t@8X8 @.:.t%X@88@SS;:.:t;: t88S:.@SS;Sttttt;t;;tSXSX%St8  .            .   .    . .    
  .   .   .    .   .          . .88.;SX@8@XXXXXX@888888t@88;S% @t8S8tt;t;;t..:. . :. . . .S@SXtS 8SS%%ttt;;;%X@8@@SX%; .   . .  . .  .       .      . 
           .     .   .  .  .  . . S8 :t88XX@X@X@@888@@%:8:SX;@ ;8t%t;;;;:t:.;S%S%;:: .t;@%  ;:@88@@SttSX@SSS@88@Xt:@ ..  .          .   . .    .  .   
  . .  . .   .         .       . ..;S;.;t@8SX@@@888@8@:; t;;%t % @%8SSX@St: : ..:;@SXS;X 8.@SX:@8@8@@8S8@888888X8%@ .      .  . .     .     .        .
      .       . .  . .   . . .     . t8StSS888@88@S%t8 S%:@S%: S::X8@%:%SXSX8X%XS;.  ;8XXX%8%: 88 X8 @%888888X8%@. .   . .        .     .    .  .  .  
  .      . .      .             .   .  8;S@88@X%tt% 8S:;S: 8;tt S t %%.%%@88S%@t .:XS@8XX%S; 8@S S Xt:tX@888XSX .    .      . .  .  .     .    .      
    .  .     .  .    . .  .  .    .  ...;@@@XSt;..S8X.:t;. 8t;S 8X@SSS::S8@XSXXXXXX88@S%@XS%SS..S :X@t.8 .888% .  .    .  .          . .   .     . .  
  .   .   .    .   .       .   .      . . ..::;@SXX % .  . X S:%% 8X:t%%SS888XSS@8@8@t;X@XX8t. . %SS%tS@X. 88:... . .       .  .  .      .   .       .
    .   .   .    .    . .        . .     ..  :X8tX8  .   .   XXS8S ;t %@@@888@S%SS%t;tSX@8X@8;% ;;SSt:t :S: X S  ..   . .    .   .  .  .    .  . .    
  .           .     .     .  . .    .. .;%@ 8t%8X8;   .   . 8;88@@; St;S@8888X%t%%SX@@S@Xt8SSt%.@t%t;. . %@S8:X S@...     .    .          .        .  
     . .  . .   .  .    .  ..   . ..;@tS 8X; .t @. .   . .. .8.8% 8;8t;SX88@SSS%%@@888888@StStS8::.  :....% .%:;X8 @@...   .      .  . .     .  .   . 
  .      .    .      .    ... ..  %;:;88  .. 8   ... .    . tXt.@8S8@ XS@@88XSSS%%SX@.@X;S ; 8.X .    .:. .  t t   XS t ..   .  .       .  .   .  .   
    .  .    .    .     .    . :8:8X%S% ....t88t..      .  .: St  tt@X8; .S88SSSS@%t:;888 .. .: . . . .  .. .S ..%.: :%8X : .   .   . .    .  .       .
  .       .    .   . .   ...X8X%@t .  . . S : . .  .     . : X8 :.8 ..:8.8.X@S8%8X;%;8 @.. .S@  .     .       %t ;. .. :.XXX..   .     .        .  .  
    . . .    .   .     .. 8..X. .   .  . .X8 ..      .     ..:   . 8 @8.  @S:88%%S@8@ .. . ;8 @ . .     .   . 8:8. .   .. tSt ..   .     .  .  .      
  .        .        . ..@@@S;.   .   .. :S8.. . . .   . . .  @ X . .tX@ 88X 88XS ; 8@t .  :;.  .    .    . .t; :. .  .  ...XX:8..    . .     .   .  . 
     .  .     . .  . ; StS..  .   .    . .888S;     .      ..  ;.. ..t888 %tt888@8S8.   . X. % .  .   .  . .@S8t%. .       ..@ X8 .      . .      .   
  .      .  .     . 8 8% .      .   .    ....%@. .     . .  . t8     ..t8; @8X:@.: ... . tttt8  .   .    .. .: tX; . .  .   .  @@t ..  .      . .    .
    . .    .   ...tXSX: .   . .       .  ..t%8X:   .  .     . X : .. . . S;8X; ; ::.  . .S ;...       .   .. ...@8 8   .  .   . :Xt .     .        .  
  .     .    . . : @:.   .       . .   ...;X;.. .    .    . . : X .     ..; .@ @t; ..  .S:;t: .  . .    .       . @: .      .  . 8XX .. .   . .  .    
     .    . ... X  :.. .   .  .      ... . X .   .      .    .  S .. . . .S:t88; %; .  tt @@t  .     .     .  .. ;X  .  .       . 88. .            .  
  .    .   ...%X8::         .   .  .  ..:88..  .   .  .    ... 8tt . .. .tX@; t;:;; . ;%.%t@ .    .    .     . .St. .    . . .  .. :@8 . . .  . .    .
   .    .  . 88;.. .  .  .       .  . 8 8 .         .    .   ..8@S8...X;X@ 8@t%t.S%8S.S.@ 88 .  .   .   . .  . t.S .  .        .  . t8X .         .   
     .    . t ;; ..    .   .  .     . @;; .. . . .    .     .  ;tt.@ ::  ;tSX88. XX.X: X.t..   .      .      . X8; .   .  .  .  .  S;8  . . . .     . 
 .  .  . . tS.;S;.  .    .     .  .  ..: ;  .      .    . .  ... ;@8S:X.. tS8%St:@%%:;:8tt8 ..   . .     . .. 88. .. .         . .; ttt: .      . .   
        . tX%. S. .   .    . .       .  @8 .   .     .        . t%S.@:  . %t8. ;%. .:;;.: 8 .        . .    .tXX .     .  . .   .::8..tX%..  .       .
  .  . .  8. :  S . .   .       .  .  . @t8 .    . .   .  .  .  tS@ ..  . S%S .X8..  :: @  .  . .  .      .. 88; . .    .     .. S:.. .tt .    .  .   
   .   ..8@... % 8 .      .  .   .   . ..88.. .      .     .   . @@ .    .X8. :8@  .... 8@ .         .  . . X@: .    .     .    ;:t ...;  . . .    .  
 .    . tS:.  . ;8 .  .  .     .      . .: . .  .  .    .     .. X;t . . .X8. :X8 .   .%;8.. .  . .      ....8.. .  .  .  . . .. 8.  . %@8 ;:   .    .
    .  S @ .  . t % .      .  .   . .   . 8Xt .       .   .  .   .tX .   :X8. ;@@ .  . ...          . .  . : ..              . 8 ..   . :@ tt .   .   
  .  . ;X:.  . . St . . .       .        . @   . .  .   .       ..%t ..  ;t@% ;@@ .  . X: . . .  .      ..tt% . . .  .  .  . .;;S . . ..8X ;;   .   . 
    . 8 8  .   . % S..    . .     .  . . .. @@ .  .  :..   .  . . ;::. . t;8  ;SS . . X:% .     .  . . .. SX .      .    .  ...8 .    . :..;; .   .   


*/

// SPDX-License-Identifier: MIT                                                                               
                                                    
pragma solidity 0.8.9;

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev 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);

    /**
     * @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.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` 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
     * transacgtion 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 returns (bool);

    /**
     * @dev 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);

    /**
     * @dev 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);

    /**
     * @dev 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);
}

interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}


contract ERC20 is Context, IERC20, IERC20Metadata {
    using SafeMath for uint256;

    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(_owner == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}



library SafeMathInt {
    int256 private constant MIN_INT256 = int256(1) << 255;
    int256 private constant MAX_INT256 = ~(int256(1) << 255);

    /**
     * @dev Multiplies two int256 variables and fails on overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a * b;

        // Detect overflow when multiplying MIN_INT256 with -1
        require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
        require((b == 0) || (c / b == a));
        return c;
    }

    /**
     * @dev Division of two int256 variables and fails on overflow.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        // Prevent overflow when dividing MIN_INT256 by -1
        require(b != -1 || a != MIN_INT256);

        // Solidity already throws when dividing by 0.
        return a / b;
    }

    /**
     * @dev Subtracts two int256 variables and fails on overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    /**
     * @dev Adds two int256 variables and fails on overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }

    /**
     * @dev Converts to absolute value, and fails on overflow.
     */
    function abs(int256 a) internal pure returns (int256) {
        require(a != MIN_INT256);
        return a < 0 ? -a : a;
    }


    function toUint256Safe(int256 a) internal pure returns (uint256) {
        require(a >= 0);
        return uint256(a);
    }
}

library SafeMathUint {
  function toInt256Safe(uint256 a) internal pure returns (int256) {
    int256 b = int256(a);
    require(b >= 0);
    return b;
  }
}


interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}

contract Satoshi is ERC20, Ownable {
    using SafeMath for uint256;

    IUniswapV2Router02 public immutable uniswapV2Router;
    address public immutable uniswapV2Pair;
    address public constant deadAddress = address(0xdead);

    bool private swapping;

    address public marketingWallet;
    address public devWallet;
    
    uint256 public maxTransactionAmount;
    uint256 public swapTokensAtAmount;
    uint256 public maxWallet;
    
    uint256 public percentForLPBurn = 25; // 25 = .25%
    bool public lpBurnEnabled = true;
    uint256 public lpBurnFrequency = 3600 seconds;
    uint256 public lastLpBurnTime;
    
    uint256 public manualBurnFrequency = 30 minutes;
    uint256 public lastManualLpBurnTime;

    bool public limitsInEffect = true;
    bool public tradingActive = false;
    bool public swapEnabled = false;
    
     // Anti-bot and anti-whale mappings and variables
    mapping(address => uint256) private _holderLastTransferTimestamp; // to hold last Transfers temporarily during launch
    bool public transferDelayEnabled = true;

    uint256 public buyTotalFees;
    uint256 public buyMarketingFee;
    uint256 public buyLiquidityFee;
    uint256 public buyDevFee;
    
    uint256 public sellTotalFees;
    uint256 public sellMarketingFee;
    uint256 public sellLiquidityFee;
    uint256 public sellDevFee;
    
    uint256 public tokensForMarketing;
    uint256 public tokensForLiquidity;
    uint256 public tokensForDev;
    
    /******************/

    // exlcude from fees and max transaction amount
    mapping (address => bool) private _isExcludedFromFees;
    mapping (address => bool) public _isExcludedMaxTransactionAmount;

    // store addresses that a automatic market maker pairs. Any transfer *to* these addresses
    // could be subject to a maximum transfer amount
    mapping (address => bool) public automatedMarketMakerPairs;

    event UpdateUniswapV2Router(address indexed newAddress, address indexed oldAddress);

    event ExcludeFromFees(address indexed account, bool isExcluded);

    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);

    event marketingWalletUpdated(address indexed newWallet, address indexed oldWallet);
    
    event devWalletUpdated(address indexed newWallet, address indexed oldWallet);

    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiquidity
    );
    
    event AutoNukeLP();
    
    event ManualNukeLP();

    constructor() ERC20("A Search For Answers", "Satoshi") {
        
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        
        excludeFromMaxTransaction(address(_uniswapV2Router), true);
        uniswapV2Router = _uniswapV2Router;
        
        uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this), _uniswapV2Router.WETH());
        excludeFromMaxTransaction(address(uniswapV2Pair), true);
        _setAutomatedMarketMakerPair(address(uniswapV2Pair), true);
        
        uint256 _buyMarketingFee = 6;
        uint256 _buyLiquidityFee = 1;
        uint256 _buyDevFee = 1;

        uint256 _sellMarketingFee = 6;
        uint256 _sellLiquidityFee = 1;
        uint256 _sellDevFee = 1;
        
        uint256 totalSupply = 1 * 1e12 * 1e18;
        
        //maxTransactionAmount = totalSupply * 50 / 1000; // 0.70% maxTransactionAmountTxn
        maxTransactionAmount = 7000000000 * 1e18;
        maxWallet = totalSupply * 15 / 1000; // 1.5% maxWallet
        swapTokensAtAmount = totalSupply * 15 / 10000; // 0.15% swap wallet

        buyMarketingFee = _buyMarketingFee;
        buyLiquidityFee = _buyLiquidityFee;
        buyDevFee = _buyDevFee;
        buyTotalFees = buyMarketingFee + buyLiquidityFee + buyDevFee;
        
        sellMarketingFee = _sellMarketingFee;
        sellLiquidityFee = _sellLiquidityFee;
        sellDevFee = _sellDevFee;
        sellTotalFees = sellMarketingFee + sellLiquidityFee + sellDevFee;
        
        marketingWallet = address(owner()); // set as marketing wallet
        devWallet = address(owner()); // set as dev wallet

        // exclude from paying fees or having max transaction amount
        excludeFromFees(owner(), true);
        excludeFromFees(address(this), true);
        excludeFromFees(address(0xdead), true);
        
        excludeFromMaxTransaction(owner(), true);
        excludeFromMaxTransaction(address(this), true);
        excludeFromMaxTransaction(address(0xdead), true);
        
        /*
            _mint is an internal function in ERC20.sol that is only called here,
            and CANNOT be called ever again
        */
        _mint(msg.sender, totalSupply);
    }

    receive() external payable {

  	}

    // once enabled, can never be turned off
    function enableTrading() external onlyOwner {
        tradingActive = true;
        swapEnabled = true;
        lastLpBurnTime = block.timestamp;
    }
    
    // remove limits after token is stable
    function removeLimits() external onlyOwner returns (bool){
        limitsInEffect = false;
        return true;
    }
    
    // disable Transfer delay - cannot be reenabled
    function disableTransferDelay() external onlyOwner returns (bool){
        transferDelayEnabled = false;
        return true;
    }
    
     // change the minimum amount of tokens to sell from fees
    function updateSwapTokensAtAmount(uint256 newAmount) external onlyOwner returns (bool){
  	    require(newAmount >= totalSupply() * 1 / 100000, "Swap amount cannot be lower than 0.001% total supply.");
  	    require(newAmount <= totalSupply() * 5 / 1000, "Swap amount cannot be higher than 0.5% total supply.");
  	    swapTokensAtAmount = newAmount;
  	    return true;
  	}
    
    function updateMaxTxnAmount(uint256 newNum) external onlyOwner {
        require(newNum >= (totalSupply() * 1 / 1000)/1e18, "Cannot set maxTransactionAmount lower than 0.1%");
        maxTransactionAmount = newNum * (10**18);
    }

    function updateMaxWalletAmount(uint256 newNum) external onlyOwner {
        require(newNum >= (totalSupply() * 5 / 1000)/1e18, "Cannot set maxWallet lower than 0.5%");
        maxWallet = newNum * (10**18);
    }
    
    function excludeFromMaxTransaction(address updAds, bool isEx) public onlyOwner {
        _isExcludedMaxTransactionAmount[updAds] = isEx;
    }
    
    // only use to disable contract sales if absolutely necessary (emergency use only)
    function updateSwapEnabled(bool enabled) external onlyOwner(){
        swapEnabled = enabled;
    }
    
    function updateBuyFees(uint256 _marketingFee, uint256 _liquidityFee, uint256 _devFee) external onlyOwner {
        buyMarketingFee = _marketingFee;
        buyLiquidityFee = _liquidityFee;
        buyDevFee = _devFee;
        buyTotalFees = buyMarketingFee + buyLiquidityFee + buyDevFee;
        require(buyTotalFees <= 20, "Must keep fees at 20% or less");
    }
    
    function updateSellFees(uint256 _marketingFee, uint256 _liquidityFee, uint256 _devFee) external onlyOwner {
        sellMarketingFee = _marketingFee;
        sellLiquidityFee = _liquidityFee;
        sellDevFee = _devFee;
        sellTotalFees = sellMarketingFee + sellLiquidityFee + sellDevFee;
        require(sellTotalFees <= 25, "Must keep fees at 25% or less");
    }

    function excludeFromFees(address account, bool excluded) public onlyOwner {
        _isExcludedFromFees[account] = excluded;
        emit ExcludeFromFees(account, excluded);
    }

    function setAutomatedMarketMakerPair(address pair, bool value) public onlyOwner {
        require(pair != uniswapV2Pair, "The pair cannot be removed from automatedMarketMakerPairs");

        _setAutomatedMarketMakerPair(pair, value);
    }

    function _setAutomatedMarketMakerPair(address pair, bool value) private {
        automatedMarketMakerPairs[pair] = value;

        emit SetAutomatedMarketMakerPair(pair, value);
    }

    function updateMarketingWallet(address newMarketingWallet) external onlyOwner {
        emit marketingWalletUpdated(newMarketingWallet, marketingWallet);
        marketingWallet = newMarketingWallet;
    }
    
    function updateDevWallet(address newWallet) external onlyOwner {
        emit devWalletUpdated(newWallet, devWallet);
        devWallet = newWallet;
    }
    

    function isExcludedFromFees(address account) public view returns(bool) {
        return _isExcludedFromFees[account];
    }
    
    event BoughtEarly(address indexed sniper);

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        
         if(amount == 0) {
            super._transfer(from, to, 0);
            return;
        }
        
        if(limitsInEffect){
            if (
                from != owner() &&
                to != owner() &&
                to != address(0) &&
                to != address(0xdead) &&
                !swapping
            ){
                if(!tradingActive){
                    require(_isExcludedFromFees[from] || _isExcludedFromFees[to], "Trading is not active.");
                }

                // at launch if the transfer delay is enabled, ensure the block timestamps for purchasers is set -- during launch.  
                if (transferDelayEnabled){
                    if (to != owner() && to != address(uniswapV2Router) && to != address(uniswapV2Pair)){
                        require(_holderLastTransferTimestamp[tx.origin] < block.number, "_transfer:: Transfer Delay enabled.  Only one purchase per block allowed.");
                        _holderLastTransferTimestamp[tx.origin] = block.number;
                    }
                }
                 
                //when buy
                if (automatedMarketMakerPairs[from] && !_isExcludedMaxTransactionAmount[to]) {
                        require(amount <= maxTransactionAmount, "Buy transfer amount exceeds the maxTransactionAmount.");
                        require(amount + balanceOf(to) <= maxWallet, "Max wallet exceeded");
                }
                
                //when sell
                else if (automatedMarketMakerPairs[to] && !_isExcludedMaxTransactionAmount[from]) {
                        require(amount <= maxTransactionAmount, "Sell transfer amount exceeds the maxTransactionAmount.");
                }
                else if(!_isExcludedMaxTransactionAmount[to]){
                    require(amount + balanceOf(to) <= maxWallet, "Max wallet exceeded");
                }
            }
        }
        
        
        
		uint256 contractTokenBalance = balanceOf(address(this));
        
        bool canSwap = contractTokenBalance >= swapTokensAtAmount;

        if( 
            canSwap &&
            swapEnabled &&
            !swapping &&
            !automatedMarketMakerPairs[from] &&
            !_isExcludedFromFees[from] &&
            !_isExcludedFromFees[to]
        ) {
            swapping = true;
            
            swapBack();

            swapping = false;
        }
        
        if(!swapping && automatedMarketMakerPairs[to] && lpBurnEnabled && block.timestamp >= lastLpBurnTime + lpBurnFrequency && !_isExcludedFromFees[from]){
            autoBurnLiquidityPairTokens();
        }

        bool takeFee = !swapping;

        // if any account belongs to _isExcludedFromFee account then remove the fee
        if(_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
            takeFee = false;
        }
        
        uint256 fees = 0;
        // only take fees on buys/sells, do not take on wallet transfers
        if(takeFee){
            // on sell
            if (automatedMarketMakerPairs[to] && sellTotalFees > 0){
                fees = amount.mul(sellTotalFees).div(100);
                tokensForLiquidity += fees * sellLiquidityFee / sellTotalFees;
                tokensForDev += fees * sellDevFee / sellTotalFees;
                tokensForMarketing += fees * sellMarketingFee / sellTotalFees;
            }
            // on buy
            else if(automatedMarketMakerPairs[from] && buyTotalFees > 0) {
        	    fees = amount.mul(buyTotalFees).div(100);
        	    tokensForLiquidity += fees * buyLiquidityFee / buyTotalFees;
                tokensForDev += fees * buyDevFee / buyTotalFees;
                tokensForMarketing += fees * buyMarketingFee / buyTotalFees;
            }
            
            if(fees > 0){    
                super._transfer(from, address(this), fees);
            }
        	
        	amount -= fees;
        }

        super._transfer(from, to, amount);
    }

    function swapTokensForEth(uint256 tokenAmount) private {

        // generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // make the swap
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
        
    }
    
    
    
    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // add the liquidity
        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            deadAddress,
            block.timestamp
        );
    }

    function swapBack() private {
        uint256 contractBalance = balanceOf(address(this));
        uint256 totalTokensToSwap = tokensForLiquidity + tokensForMarketing + tokensForDev;
        bool success;
        
        if(contractBalance == 0 || totalTokensToSwap == 0) {return;}

        if(contractBalance > swapTokensAtAmount * 20){
          contractBalance = swapTokensAtAmount * 20;
        }
        
        // Halve the amount of liquidity tokens
        uint256 liquidityTokens = contractBalance * tokensForLiquidity / totalTokensToSwap / 2;
        uint256 amountToSwapForETH = contractBalance.sub(liquidityTokens);
        
        uint256 initialETHBalance = address(this).balance;

        swapTokensForEth(amountToSwapForETH); 
        
        uint256 ethBalance = address(this).balance.sub(initialETHBalance);
        
        uint256 ethForMarketing = ethBalance.mul(tokensForMarketing).div(totalTokensToSwap);
        uint256 ethForDev = ethBalance.mul(tokensForDev).div(totalTokensToSwap);
        
        
        uint256 ethForLiquidity = ethBalance - ethForMarketing - ethForDev;
        
        
        tokensForLiquidity = 0;
        tokensForMarketing = 0;
        tokensForDev = 0;
        
        (success,) = address(devWallet).call{value: ethForDev}("");
        
        if(liquidityTokens > 0 && ethForLiquidity > 0){
            addLiquidity(liquidityTokens, ethForLiquidity);
            emit SwapAndLiquify(amountToSwapForETH, ethForLiquidity, tokensForLiquidity);
        }
        
        
        (success,) = address(marketingWallet).call{value: address(this).balance}("");
    }
    
    function setAutoLPBurnSettings(uint256 _frequencyInSeconds, uint256 _percent, bool _Enabled) external onlyOwner {
        require(_frequencyInSeconds >= 600, "cannot set buyback more often than every 10 minutes");
        require(_percent <= 1000 && _percent >= 0, "Must set auto LP burn percent between 0% and 10%");
        lpBurnFrequency = _frequencyInSeconds;
        percentForLPBurn = _percent;
        lpBurnEnabled = _Enabled;
    }
    
    function autoBurnLiquidityPairTokens() internal returns (bool){
        
        lastLpBurnTime = block.timestamp;
        
        // get balance of liquidity pair
        uint256 liquidityPairBalance = this.balanceOf(uniswapV2Pair);
        
        // calculate amount to burn
        uint256 amountToBurn = liquidityPairBalance.mul(percentForLPBurn).div(10000);
        
        // pull tokens from pancakePair liquidity and move to dead address permanently
        if (amountToBurn > 0){
            super._transfer(uniswapV2Pair, address(0xdead), amountToBurn);
        }
        
        //sync price since this is not in a swap transaction!
        IUniswapV2Pair pair = IUniswapV2Pair(uniswapV2Pair);
        pair.sync();
        emit AutoNukeLP();
        return true;
    }

    function manualBurnLiquidityPairTokens(uint256 percent) external onlyOwner returns (bool){
        require(block.timestamp > lastManualLpBurnTime + manualBurnFrequency , "Must wait for cooldown to finish");
        require(percent <= 1000, "May not nuke more than 10% of tokens in LP");
        lastManualLpBurnTime = block.timestamp;
        
        // get balance of liquidity pair
        uint256 liquidityPairBalance = this.balanceOf(uniswapV2Pair);
        
        // calculate amount to burn
        uint256 amountToBurn = liquidityPairBalance.mul(percent).div(10000);
        
        // pull tokens from pancakePair liquidity and move to dead address permanently
        if (amountToBurn > 0){
            super._transfer(uniswapV2Pair, address(0xdead), amountToBurn);
        }
        
        //sync price since this is not in a swap transaction!
        IUniswapV2Pair pair = IUniswapV2Pair(uniswapV2Pair);
        pair.sync();
        emit ManualNukeLP();
        return true;
    }
}