ETH Price: $4,176.30 (+7.10%)

Transaction Decoder

Block:
12427020 at May-13-2021 04:12:27 PM +UTC
Transaction Fee:
0.24844148 ETH $1,037.57
Gas Used:
1,774,582 Gas / 140 Gwei

Emitted Events:

Account State Difference:

  Address   Before After State Difference Code
(zhizhu.top)
2,126.306418229430067028 Eth2,126.554859709430067028 Eth0.24844148
0x53c538Ae...a6eE4B435
(Pension Plan: Deployer)
1.66 Eth
Nonce: 0
1.41155852 Eth
Nonce: 1
0.24844148
0xF32aa187...d0D107574
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 4778859992719145074122115357515057017871363283313389002199033590221071036724754570437178779543817641465479543711090610279892917471012466815931411203527012766051297326106535297257891151776966808197088160950967956311980025274251198264020788793039655263641257597480096875418006594077164881932143279589153973974307984853341475893423093566120653907198455117209663891463243159401696801028050815298685137654266571930424334128331625312784830652464324356955914889203013612992856543204538673213453272462329248402071202511961254284786733630957333399012128061448312135062356390507823041693012018672561589238648577539559964499757328372016446531061877943695127923197469626117107875549791028225319736310058684258569637450506020765126727162076769248720395114220639311134640586827266327750771658591019825973821377989958210911356481578649304838749509885504646061834599314455767470301467634670919730277965883502933148775140233060237750952877079220043021265906756535341576932068999905519217731615367501408397026988277289786458099743986743020965827834685993789004863101189533456656486282825900372559411109158925393869422662638784360165284080280071462212045292617528097871276557902805045815695922946141766845254882026200312030285296513609517929293392523363232562809124348044011085824856470445795863663980701532649722606994135885585221679941990081195045735284315876135101445087778947064894621806935171467946508429498287940011830424870282284753021770921660687034709230845591166228698372047884126472142550780534604890633369051853271809780114007512739613547377331032255702440691498328151699235972055300388298912112743446570338739579834859148988250051378585349553242458054613349284387430812930696562469273396157611236259810431483849556047472251098578216066499654361804593791892813186035570624581501651104693243561505178838223808439228772567592597466379104943862142025364286094324493905205242279939872591083237454053214757699448409177491138276805823737435430816350746379403660168107400351960936061862650535053422887577420465153016328654148175217381051979840953648058774623212819945705713333650516465205340643840035866925763256585544414120828573477642389526599363776091286803419242663032400957013895217487005506644881573478398099951017898377483774844218951491567628572913761118901790501001059013087688738203932579673905525480769930293661008925904700751361698709391711359005086662595738356330473300843529745960229884089372250981011671894370653037946888854911995266399062537911798602226284129501237997175358590017826844631040114249566667031838104114899833439263641997653438291479600258774961519421159394790066660610552596881981677394750116396235837189616220038681415328212742363126787116723704934110713060479959050768121861732761486457489569834132562283075075778264899567033398549768065942693867928681266939589065412040175103773004871305964630515929403764202638584022196413453256580164469913006841960363626178457505099507894151177408551258543686208614849029748560804657917420567079916068974699657704362789869140871732448575756187119031739782766733894429046652668144475957200625621176868210233521803910629426633345666525904867363132599307835263310792341596834523094167718471007130317978716844345020693667722064255628161380651253707429976740415801112175907677251986153777168670137840270107007014976836953450025442794451812189726581347572416519579329929758565214382635824195967014698660740919765652924690608645363047216451349656112813132211331771225099704006188435889086923775792735808478158845623340928254391372764661652163040315829097876854103685589969671998915921272559671083456752863304915890970424863387779193655876433249825492519169250484034139423708561034061005337854831642916999368715318395249820289041610901729431740988355134831458480832306108341891590384124824807216262113635505586627041536734716662217814768626391250204074032583719263204870638047703741310289102098349291900112057736749285074156318484480421679028703328282550427863336058682636652176964573154922602106701387065602251024411699069149769234981376131671577216011296625468747511565511277987289119385630997286531802873987619737580865541390453723925891445284404048559287003073708789385551571137981623752304150737375866556388828931732024412488805701430375317721333554234320035967478232425524099522259630278053616728311145113814470766271396866144593364064923032899136159055125569083364255902368752522981881100572119268212633569832103632831937211330610237985315323854372988346986624819212032888395633820425123878330834209763449625887102141672695589736172282678279865641045248871291127106705006316815750840882154983604947410801328058858412349273423056460622729837642510882649838947676414804913839435409938808780080523540110694929091068855747846576450969851781895934339294100630744615609199912510499284831704003738481988117980461742655869465150379490520342617768871737117545661706482877380365322997329695086257030543830355216508641923114180385160947274136647857665002715912690140194159127119581947726025562166317454543339037335352092156991414616411148630170820918935905882197297018545966116490480564467076647136692038059967276452724109931188246566940039825797931377298034490065573532283037055802965106616324390076991978760005170734780152497437927390502739871176859084605132245774497332377862491844344101798687089113293892624038663635281586334914774542923612025553516348172097301264045103726485120811190656492612136317279623891812237215990005122733928296283477599550711434227320410659868318692264484095505988398642086042204191305554827287971001358250547420458195798648465213078434116439789892155636283439337018843540255395509321061619236830327759256913077097601670094576244367743413362511321284347856665006519035467101273805872205151647272070874260072148744754157410363943432575946493514437887356833731205629106005434971217603914431488365218610597670441866509901538551319617157248872566745256671768065371171411385732704271243308832433126630854238712917614915306534993147949597150476166720036201931838344648701653972005902923865939120356981933250051660839363001025778284619977828741356600090389062816886112928420733003631069252341421686868583780554073716277890737074559305172153267683574705337787865945193781083881543852265680259876902000057399657221205647294236121541049963868280329928868218909622551030038254683513239048953687009163550170296644570971932796005323206778803444295817823387644124036043385610765065934546005251643639483824119366095732270347683721624869928137890092611464970364828126869313016274806401598394296847187147104525179585188654572524848449410490770272725102723539134855718172978122464070530174001961872834738538428083891406984063952912663403219098669926588980430688788919444307784296261701424414627435004939040503099571673208383547150749492490850223198158320071722697517103758792244779331777232892719868030541682934135944628803931587657495223552247884724448714038338582612358513744481400047408704198157215704157629740722850468239549178534083402252303974162505106729252006255635915101664179098043921397452148124030779398613231374851452606751881105037007081726497822951635196552976859467036940376475258479412504699992889643715398332700757374965922429148648508702714256907484768745763361588373507669361671424491896819731925279532776189020292780583413616970597063476840568079751457607393188931138681423067787917330723798269677824765217616410297420599005575066030224485816324694451329307478521762274897007348633428153580162052186864984328658197099101464773882807120894858212841049327448164567418047913701786491683286570356113421828237880213489849021960329124517770611505335586616030964120539931875815653675867449408289735326771793919495232487710826293029089528543179698388031177884230782900544390563609978860700646300079699469448257807081775343037723741082523306147121624508258870489101776772646788210374186467802610313853513542168125491166676107702328920963134131204797375044419763344611277955806059955861529433308800407847880549927533351352290634557646775632599762936187232278767456270890203768843148645364523812812802775781194116133250310522673697783794077194839409279697167343300047932484699914713054646627829583659354508191255725575840180615785689819704634563859127283123897732000504066257065579485502998497619195017328704253360295346078870604503259278682122171910844643855402786877993370658953316192882001912111213622991471384047848189379463813785951225111000726169540205156242275794188913706592446720696831550827423750871771626298156873176569146885861992582260600266733334653494743676156763734053085162857339624525584873188788550861005245770059009238273878998780347571111403682240623474242015739490724153072235151081638778292764812951886181587380460488200661996263075838554171080713644867335040438032229336743017337625320657841913974332900640939327762522707618427834556301782276398788594481288269007776141662321619841719779983157859214409712416900875923252201591524610813599552303067769947670617600113978478417281879871227047988638077596559995053583376572816100018393640949362827837635887398655055187756552804918262483160371294862341066544081937057928967435452260490182471117057158379021440746816743796720022958592243994036982259377040002738916099728202042062510166708916323566600424241181085957863773474902272335592251107442701923530154256186694328268439725742897357558952697935976554073116673000354103496017371500151714239733142466538461635960970459925040712844264019149172692762304107238900946545129827767999785983008724007610220604676194410183489399415731189890648417078729365065172690706106396690214479431210240944895351206365942670210340845808352051783687058445207017798124767498414671688746392024734148479529812884979960084168722922628134105698171760117800344971852215169140872849045602856882537347166880998061330035890642666868156336443192780372321070923039688926114297864274917480540113892820371555968653025931064613970167087435978989762037906512859137370213788365859250168282888013122662714476716448755702010872523816978787576038558279160969020107294851477398070788471610003199776372751260594133836029077727136976677691112656033862667669516405762701513560993002146052252767360799863325791870098472848413896198878669620288298963314697561589382781731592721886850773166898277520503534978237167509384377952408394726715227739619009631560452752887509281928609956292763281333796412414059081760226019352171750101401006931268067365952272555254433798729852759136101034056120924351666001030173862084875406892750162998692083831440008269384489063562313129765403280004091059440702714789546469400160347554301694831880528077849645268471372982143610663586934894462221695514556170910214468591201686714139976197213546792015825641207192887353368012737145525424059827234169460861128519387579107381361345012490308896114122509860899204329039769111042644791487474840098838488699565695294248812125871842241325746031405945443597054006279590318128204116287600173532201940675768531124087538798523818848397422241553248453547254742101475829552947973300154458990927985050066149123342346105796951593503870235523158331511982350407843476179680893641610428248332782162252281760553524974333656988429534225565899794150531497046945968294236361642889249297964212675993465451667154284282430136330014402692448706622556717510798391765056030734746402671573756112319776059082824369146787011281267846781970351337463860532630424911929692005237681216529920321444978917562239774701242780064129081353882959487320245549859141866398493149535453626502341765276664304900192905921977526160516897780412331163863150656111450784908774099202429174589876589188567223559691395957306793939757674723434153910479386104741284266189953127834571207769929105785136808857643818855511332779812152551568795080304915837964043918739453891086204803847971587620243586930353551543384697723246247650256301090655383461793635189232560750075701014472322164275318743814286680226777000916004421450227277477758119533923004339609887743355752294298848050397490676532123435918009693328399059022726885258074169904980675583078556113709822377457992068430388436580885235026411182757693617602674649983319446548243121795672576108889627960863460626883341946980250519961138288043526471229162479247547863565046464539793893750416875363248980230503593583819494928042275511761813548163608157107110484527579900885290773319903298882968529227862677034679415067871687698406076795988751617889540585418296383555384344370920894996152985639862820514558189777773715375172145448952401613502481749201701184529164967509003518732148791950145379952603578169073922668348426457021042241184891411292844868513604134413021192286304905845238368376758875657127631722244444327825790053442846846786061250447553509437923104586751152863506481191668670797065526546931014674998028157407484163379976497166176708966939524445463159389534011945140648724651455102898141416530357049496678847786687072779472304013156642831596835668184804951577631169401435667312947363057864633564527960323016175798045640272798389111841904213136835737005152279743296961240208730680137225295204177234050812634257103266182787458522292467879819065619809336235404387961159867928285545748677189424654010669417184148715037492729452888567385462019162706852068553633541858507103180108385934477430605521245918522877351108504390436549802207630898192612829754269178549629324331949283532669589174494392820658485297909356435419956339591945729114235510180341204303132954389056054685725497635941188765285776229522189851531955134632773632809380114879082232313776816145766288759578157090501583482530330027017286771732857732992319081442798416078206691640636077125625096593608510857497575290511608403333232584790744715901064274278868306708435000853324961656055501528165806454766742164967366728546602395131276478990704245651564569489077977666257529128263350304941119053404314991939169757681582665076848549506032738067505399312924936430918430137118858765849606128833074026315180746117047856511154358073762304013357365908841040475078971868256790327167010018596690040271440653455259237965268586397296414769910275544007507838267573882805824021213208116824946159618640174886577915013371982401316864178161151691584493547173654951156816792579484943801262323649509587195107952084726941969631384148729702656025657025569008974713410028602280133019302202918884514269511268537764842847579353334369977017671351132760143275151419599433092595161131249461906336562819466017514367648279667129544301754675311606662912741879616578277781664846208723016130162467946027136213605924723485384683634267331372512754930909766909052489092236377618084728685008555560118721504592848665041352929535310139616702430937473498214375111876705574848701573360810734347896128422442607282277425162856288702329483488557912184664950224483655474650671613015366623493100058587838433398154966022302990933175329496813524793500995285776425224059340523637136224561173963939738282709394144894738332307650135813991399679885665312949167841907229407868685218929240114595284937175247654787987016918229599629744207888919841045106607843502327227332463183087965642927826005727907351169498737288851127700348815646014984105931966888789820858866703552132969944040844086813036143769319559165438047962335811269327402612889919082481582539679010294408038687390871350687928805762201646497771592138566876463863649826746541843506691752609794636746515023281597571192032911189836019995783497199509553148629162177823559536303308180743849824713008707194849446464538491204078537473652620744783371530467694871892616365462185735593735805421516762324813610679529353987477794304743159907662799713218213283442463903190775188963903882911218017575813937217536564833116220527072818555135053899876450140453563076613476174097879233436309303554218312318611313929948632309389421551420160929612001877169519466608355280384017568887906677976788048597835787644013048403735710264215109263939245257584441166834271270854829006084493629571347603476995163019112308971357460803105862848821395331986878691517306654814726512352340043987965450436506268019364075947713398688648637972305791935710485755941946866535982096303628711687952226421921951713177751161136105917703441927686055210665444094446477490420442774674423039878388054929867924932096876623734381694282008863287817895332297585977720971086582030011648836972336053629817188418932105702597526371121422106929554411353982177835276953970980642587290399531738521974725651940531233518252425818000046575250735128539851481198423358817854395691847268435153783194367909266171522343402778890893815533458770922335407558746774731811333706972792194958098116168002712216505149380183762213301061232384616816196331906565676423321013847398209807410010767223443592649587695762751679863248595235457540165082003761259853117693998821357928772287728233935863636856454082279316996063918995945428123428498620368476106679254365253742976917353759391889919278445435796354514814431036920747784688092225988530552822419791858540719365637651343000342897792982556528432413663008478605225743333406611750436597188632061874938046290264110858202407162609385115828110298913648821220617189510989944692596084577120583269742962862683573650651529175675167221843536938831067375039976781473788372241676815768458410579779793365601119354624927909399752213003448990563302256663966619777130091914478353816846466595203069315678170500829382490610891216214491872308348672117151494984807232717687777452061753088454521744474818004643314448454901454444305784079726094217992265530599337643104072158826118729915143176602638099415091

Execution Trace

HachikoInu.6d20d190( )
// SPDX-License-Identifier: Unlicensed

pragma solidity ^0.6.12;

abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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
     * 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 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);
}

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;
    }
}

library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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 () internal {
        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;
    }
}



contract HachikoInu is Context, IERC20, Ownable {
    using SafeMath for uint256;
    using Address for address;

    mapping (address => uint256) private _rOwned;
    mapping (address => uint256) private _tOwned;
    mapping (address => mapping (address => uint256)) private _allowances;

    mapping (address => bool) private _isExcluded;
    address[] private _excluded;
   
    uint256 private constant MAX = ~uint256(0);
    uint256 private constant _tTotal = 1000000000000000 * 10**18;
    uint256 private _rTotal = (MAX - (MAX % _tTotal));
    uint256 private _tFeeTotal;

    string private _name = 'Hachiko Inu';
    string private _symbol = 'Inu';
    uint8 private _decimals = 18;
    
    uint256 public _maxTxAmount = 1000000000000000 * 10**18;

    constructor () public {
        _rOwned[_msgSender()] = _rTotal;
        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

    function decimals() public view returns (uint8) {
        return _decimals;
    }

    function totalSupply() public view override returns (uint256) {
        return _tTotal;
    }

    function balanceOf(address account) public view override returns (uint256) {
        if (_isExcluded[account]) return _tOwned[account];
        return tokenFromReflection(_rOwned[account]);
    }

    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    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;
    }

    function isExcluded(address account) public view returns (bool) {
        return _isExcluded[account];
    }

    function totalFees() public view returns (uint256) {
        return _tFeeTotal;
    }
    
    
    function setMaxTxPercent(uint256 maxTxPercent) external onlyOwner() {
        _maxTxAmount = _tTotal.mul(maxTxPercent).div(
            10**2
        );
    }

    function reflect(uint256 tAmount) public {
        address sender = _msgSender();
        require(!_isExcluded[sender], "Excluded addresses cannot call this function");
        (uint256 rAmount,,,,) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _rTotal = _rTotal.sub(rAmount);
        _tFeeTotal = _tFeeTotal.add(tAmount);
    }

    function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) {
        require(tAmount <= _tTotal, "Amount must be less than supply");
        if (!deductTransferFee) {
            (uint256 rAmount,,,,) = _getValues(tAmount);
            return rAmount;
        } else {
            (,uint256 rTransferAmount,,,) = _getValues(tAmount);
            return rTransferAmount;
        }
    }

    function tokenFromReflection(uint256 rAmount) public view returns(uint256) {
        require(rAmount <= _rTotal, "Amount must be less than total reflections");
        uint256 currentRate =  _getRate();
        return rAmount.div(currentRate);
    }

    function excludeAccount(address account) external onlyOwner() {
        require(!_isExcluded[account], "Account is already excluded");
        if(_rOwned[account] > 0) {
            _tOwned[account] = tokenFromReflection(_rOwned[account]);
        }
        _isExcluded[account] = true;
        _excluded.push(account);
    }

    function includeAccount(address account) external onlyOwner() {
        require(_isExcluded[account], "Account is already excluded");
        for (uint256 i = 0; i < _excluded.length; i++) {
            if (_excluded[i] == account) {
                _excluded[i] = _excluded[_excluded.length - 1];
                _tOwned[account] = 0;
                _isExcluded[account] = false;
                _excluded.pop();
                break;
            }
        }
    }

    function _approve(address owner, address spender, uint256 amount) private {
        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);
    }

    function _transfer(address sender, address recipient, uint256 amount) private {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");
        if(sender != owner() && recipient != owner())
          require(amount <= _maxTxAmount, "Transfer amount exceeds the maxTxAmount.");
            
        if (_isExcluded[sender] && !_isExcluded[recipient]) {
            _transferFromExcluded(sender, recipient, amount);
        } else if (!_isExcluded[sender] && _isExcluded[recipient]) {
            _transferToExcluded(sender, recipient, amount);
        } else if (!_isExcluded[sender] && !_isExcluded[recipient]) {
            _transferStandard(sender, recipient, amount);
        } else if (_isExcluded[sender] && _isExcluded[recipient]) {
            _transferBothExcluded(sender, recipient, amount);
        } else {
            _transferStandard(sender, recipient, amount);
        }
    }

    function _transferStandard(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);       
        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _transferToExcluded(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);           
        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _transferFromExcluded(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount);
        _tOwned[sender] = _tOwned[sender].sub(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);   
        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _transferBothExcluded(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount);
        _tOwned[sender] = _tOwned[sender].sub(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);        
        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rTotal = _rTotal.sub(rFee);
        _tFeeTotal = _tFeeTotal.add(tFee);
    }

    function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256) {
        (uint256 tTransferAmount, uint256 tFee) = _getTValues(tAmount);
        uint256 currentRate =  _getRate();
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, currentRate);
        return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee);
    }

    function _getTValues(uint256 tAmount) private pure returns (uint256, uint256) {
        uint256 tFee = tAmount.div(100).mul(5);
        uint256 tTransferAmount = tAmount.sub(tFee);
        return (tTransferAmount, tFee);
    }

    function _getRValues(uint256 tAmount, uint256 tFee, uint256 currentRate) private pure returns (uint256, uint256, uint256) {
        uint256 rAmount = tAmount.mul(currentRate);
        uint256 rFee = tFee.mul(currentRate);
        uint256 rTransferAmount = rAmount.sub(rFee);
        return (rAmount, rTransferAmount, rFee);
    }

    function _getRate() private view returns(uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply.div(tSupply);
    }

    function _getCurrentSupply() private view returns(uint256, uint256) {
        uint256 rSupply = _rTotal;
        uint256 tSupply = _tTotal;      
        for (uint256 i = 0; i < _excluded.length; i++) {
            if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _tTotal);
            rSupply = rSupply.sub(_rOwned[_excluded[i]]);
            tSupply = tSupply.sub(_tOwned[_excluded[i]]);
        }
        if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);
        return (rSupply, tSupply);
    }
}