ETH Price: $3,799.72 (+3.77%)
Gas: 7 Gwei

Transaction Decoder

Block:
12275430 at Apr-20-2021 06:33:48 AM +UTC
Transaction Fee:
0.450673505 ETH $1,712.43
Gas Used:
2,436,073 Gas / 185 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x537edD52...9D6a6E0D4
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 1854278234780921362350048046775418581013103734056497846856316770712001979554983054123188026202879734720119910257607154115191588122769008026288124174400694036902923023189179684146168007649685629172076340031549361914941336252323292359329672875146697761802173635490358692511982270192428349051747034704116422052542559414117857799252099511234900433502706238804320312616718044760203046638490054723750945166513737263903958510734922631695588231378492252654698190204908010362013464143330911991935132530788018343679479703990804804156454264008768091446371239576621656097923393690888836609082724596488964902125309975813010690169762335495913439890148209525106431724274490494863290941316736094851632301064821168361777433402125563492301243894029935387396942175410497988994852634258905571271543949580998229186288838430382179265108755363535682532688456306801886191479513680256418506237486714805212102230900220861775438615460577427587863560652293667674773719329106635930097528921490495293030319992107555873761261411457220812766455778716483288047118009446375880151697245898760624626422400760956835268720054617820387469003030850669631540436821635989327629689316533812039143321369019197325160103442184453069937853529989060385422866493637916192380772162904967498091301275148549586189157646023096339212378704123602515359473598041582628590992853124287032277095877127332499254271455807463947779067854904364701403009391855248360938136203757741201049852940289280640856932192963551927002132204176265140501052469148611261707508266348740086883926324569387421013615255276592299394042302889650429861788663359904317524553278219013583983488376441227168240368754255842378483293665045473977128761846323418759063986253018397974209697514443129240545770875882360260324520774783512326146403802827647954224938258181457551872042035280650643050624555388259126711834357376134047118474941053471401488525319397121183183818957159601759850485048654561705991507943600789291514149996775478065443146869479153370036940714258636031299527396825612490519879843203781254633279180892477445329637114387240239526747362338753818755855463891434423900823891893449032265551755997753955198548321388664363141512909430795043279527126975452318899919360018675910787484268119939291327890081151789101912440697461234201571844525442544128532904691538001653247271893490598240651090008704741058219443190913243084107817681042887831165628351722117986919858400177578965293575539837545768811483660797654243394973959407714082914661818741679346566123399858038329388725649045482556620565295032020284679785341117660368364285097074757581706744234812426696418475448796721323255923333530727297749137619541111030535422566559366507940606401074609732705271538354673267359648181025315834244937417719023509325952671411898828087491569319341695044869697126306740896387324466437421333786198164350952612659971157637955982847111437893914864889575439034733555568968239786101863317779812597470268290539749129060226264765344879901526023591533731712349560150606261164977816428175090041117690127540977652057950212169850900215620856545465968626130587908798389417110333619141379129357317600878190417327537574237850066581361785668507756209678550245203851955535898487024682809768644081736735492478795373373347433325938529067224550195580105104588284275240242575929935374520362368223214194161848454295318276680078896897081819228389467225890424245486543723513812497409753185404431930688711981969875359576016335225190091141656306332294343188253646147978765348497200280521322688698435020899962187489179524823609137992242108108475926841015846535191595698176634292158983265733740973243840428460386393382410424802677762207006304169053875580485972505993782301285519365813317669014198877042201802957682381417131867659211607936410173725574871925820658169344393622139407041685655624409997160682567599309945926098008555760704255736805865077565621730385727446957593560152793141082300753358678790447871048281711863299506815740754558125930819956422866495169303278072544006274009008838531203538926969687952722140954369070778462534739703730074488872915640758420237439006169284607247017115779646548775764359473612104219445503739913243272308788739401189618567680132021810387374147359871351469146319939933542208041722916995316027043759521230992789534422726527662944763294222140814903367462092124769251760987952710967106874233810346012151029160665171275168771594142751006856099661005849381379773248689266121037756703295895578687636715171099590717203826460849452143942712949792449349075916858576985204111286492805649130788496413001886520898310268679572132209977924027264184637280436589203485237120673916871030999846576583062573492574469387421750904163614157450832587030680893044024719270227178649198541833711405049256687322221532087846659474661443143926043731885735101888025368545336245312785986902589091436811150331157398904184041882395100177088024031937767996030901669937275497796613395099527407043732819990965747002257286145909089393704201433802851757373931413317056781879589292210697275159349711378504022890596560471576074838658104927749925222865861953291045215455733854301965026754302045838428136904341841370008434162004102039411223235372572574427925650265968947616266809739427109354990870276852975267425732405724010478735905570841031276113111263675501448771569682706547436445248051582767989228401502829707496781984469155184985683057155725623942410599493557666255691732244994559349332092299452981658885804859619660429860201752022814410007141062325132061686817503651373962564840827873397214353804306424561222455427917163035825769989342525376564467596758644722413351075360078445225956587968838832557441947849813264292262393418996453479123909778066723055678485667975789987890261657209182268309747868829271004231248025618088017486588864112245336674088893209655858358607343710057083628775033261448219399308122995417614793349133532279938583834440802178558428732440314447699131535271394105621952804276264380360012782397801016655442403807446488523566270129542930010840588405990178438712594641806458369838854581853062095966325421189694128967254485277121819372235840330564858770770929639569604932524321225298048374116011258670557752559462087852715713209393408504384263184746555909646652430253974028674539487329058604068115193862272268766344198431077511642978976209824736697047950096575127501849555764486022344055863861638859450186055721861241766348092094052372025665308259758894014103872460238993458918544531415383708874418436888770461285067600610317464834155527242338434490060617476972466766807395066399915643639040531411941269400606365409366391505769695172409254052410612738651163009449784832290311907238002457262651128930350322586535749319493226639295062442516214418503468132139228270693114124509854390301250433060465477538901532585803118652434356552525998173845485465647868017240946151659207024487872959334640772117870308646470933121871176521806467838523268507374153340872703401871719886726797692172196277330709080185524646291462887921466722043051074006591591100644860454686927726132326407924430945126462073086384662076765859296827310431546450054014828354211534290347133971718244912291594786804556040570992936405464485122215549774018091611310057274957595064473152418958393009176315772063765410238483898507056650431990601702232514664085168486870979467003742168189284867233444863001697057401626503219781939334392866539514538500728441205532268610257324063643027497321878316466500777408564873675498104214259921618134202133803826946033564993507179072344230947850841049156664815280002134538485227508223845655774048800580627192432049643024439979218065920108799131628256121814553549396088999753436536600446707001787141359567214472875760804900789803315106981483122731064980413639627231594774440490360456441773200649066201056741609876111350860505053093055652835722185413820603097414556332056267945316691326613152320993924921148113045006412754112177191002816646045733230115765089751927238962991876540034780697580691006807074466052224485136126573596945902972279893049586293179706471352953652061139967449398819224850578730544391038383045693778680510953344920190581753754597254276505175489374675767688858327971782906155328890830922467608980892064814271809358080428469616395114042335271926389832384213561155563820586544762872919977609488830539595251061105960894310647314433810254111893983133319787560349582964413816311166627017426708701149124368072287641838590969846675204708249538314395879540680585659023205681230181300201201698932266060970400494859944675620097286670389370072670913046402037900403690999670517820481048640842379705232962642388356148388149467015093740172489085488130523068823446061947833516628709246034962702649046054710600003916652238897501710250365042842409527180081731913820611461337643532799202908036108541114072453012351895268351450555051555160230359926561002403626529362307375171077837394598320259508478414829666081010131108350311333979207277345876605619791735728320581743151626892005668924290282965118248574353655935689841142114538746795742272493571442293279781548626721262768643044637228958101109969764048936596743473845037586604680858032680850660561445969928985427206817954066450401418270257427588005871174358422869476698592543479466171306482535886817736887904043465980904344118514244374865805539782701877883843836752235197137156357072417503929525123686686973304093137064194154379118910699951808687348056514300624299045586507243421326835336543576303176303162537558816370783669368681123000359008293449939117475378360049122413647119158806042613807289355924452953432297497373070177404995088842998337304768717791701422783138715087479273834556643312971656720642113518886465912196489215621833218741600208301423551596294993438922110915279003439771925863097003547898321329235898362879885902215445172489216431558596565190600049772409238381508663244374560355995345543098586724381845468146524524187875770583976690551718237501113019986545718483032335788684323513057418378062221137778520883325046195483582108564444703701143719820697470474638982204417958404466322747325948337382908059528341687061059687422632672326965896626842159420086865801715502391878592555918403484655884056097766829644475487828116577953499109898337639662787601063827094649131137911195733297923719301918655120915259735219780584925812455480250662718872199730618678809019426196714265687668290335533546509668954035552756061487166342607692438045392216353486253798322192519174372369865798983001452462877090075169878750380921917800881528770747811234868046028808406914336271415484274468146101523151883226565098043464334501894353273998467113115829596793366111998867110975180430859236357891943975783234246200758014038261071797399183348383359977580660137845598511165062516120539129426319822860715459402472083954952581121473633605136605532459017045681088889158675711172867670028889653240816648458642806963748194124704299719733184837739871651219816247067596441278908883197991227200727701618967145884397991737833855441851565208352944004283306159392816933491985731437239037763463170687419578944633666940132579343803217307990615119312437411465949058711219221721342205840888986455051121517942319486710878376290723942737704183313546314868929789786242493790776277628664510194702759957414684680840776802824664834642555537988542930061225086862432866440877207787614926356138481047115162065486348057144013518968719352297490375885599474260469306676461681071473957593010191181107520142042415167257298570778586817365868130683087207125373947241319485168453050386174740832652125802243291929534144886992660340280440584898422374691722324011711142332448727931950921360581324381980388139110565971126641519776301226132961446650733361999906074750081367710406957067173610438133393541535631189172703264369140880679907389708299238033481525652287199282060909900697923606614712705165006154459930222430800699240101254329276226340706079533150393619895938201729676101162937934461932258791602557616731679036906519065054618072167329252649678333196044329223779339840718918574852146548595089008237855752371312822484819672885299198116626141741997815005611455467043333803731880921162102543199788230043920132193814150670557454570331763151823808934172386798423602406218338501926044736070820006475162466394412346388363849278849478865187542977972546514107083921608515823970549535932070484993439839480879535938459276861826684056868704294582033887405584439697204050339952979394448265891859440679800311361156866013084232847009858868686108620754982737622045960107582566377275878436336698247939199129205825592783348828251824062637489876025142622166423162755490949944625412332909420396535658386041455682460334031816779727634425259654553255717786294148745671422345259152665661943682028695061659845788394730543196892958720595565776734178071542689794725615340834860109453862259088551069748908665824054248014453309474196124875633221687397801558195786779792413398836890855073094605504407377440259259018841042908120319138972994977754796860613035883418857920655676198636448531298078799984906201319839586478195310048216281940003914878031324665290849570169951057913328594677145946341084411427741890567636055478980079934091468867029205466182919569360476871814742729606393852945633684621359226538138533879875061175563805213558127630037845145257358820283053771054320860420326723432240556313724396199281660217826831053390768298916050881256280882001614005985088806798363728905686602820385582831497331024018662145589917511965230223314367819980927057838976658914568541452608379774282770762460892078046922681316865840786480319856442619132367947456664816436142565238738866427523591022903523722270505027697429699195401946002164629179146673428072507008245066116894104163694453320251852477897401822518539285175037244520288719575441942603275001302968286709722357109534360208376300424922875543585022385792534526515911748869109692442238573680862048058032480651131526695859670568564096362231752679091312746908944310418016429107599671356722714910188385558862820849008316647149422125306501354584244536005506131002890800058111663415345674538998548949434292112461223559514185144126102305717945696022993318060431787444830702678344487542928679320611906913702257323771477709283184867345011587681688821849328929952229177445561066468567966671761777977917514157948987468842306274740650902521744430123341996001632752897339441220809288831157488105197795852400264874287600512245502284999152070632757777963303306742331152300944230107924908951941058408257006340007681638021488669015964246418271513043977863260595724891440058001816099124835911170013359485915875944236486823669032058171289417108815463729126573009382518670620415342080067574534227933486828518321490825701131889620625171722655698951322090165648766130003132583737064523608691596091334145242427797942428182749746043207121817092119541496147076495267785300213002883144807204568266279946620746326992692259157067793192721016555341383369809610803155826694993472257077944180135490803688304845498041933433793011444631248657444848323196604839916705047860535212971579750672260577868593700623782250885765760620139013658021944059756960827641092305430590331942320599187184393723486133505866547105771443815402744200855305408216298511997842031857737251138614171150958257089162333332634477494911174689856549166856141027699175268993064803638117427689444472484368186197247004646075502241135424723703474810607459528362835595724206116080149498228111267536473456459473960209246730590849326282915292144500445421643516876435625875428181084045970320562367439012197028802107553233662621741100983775323034067296865407551633938968869032575468419476344385907745871374201090710145700017087657406821054894756798455743837013454216515007756419815529098336788554774338278704325741254356089938966074612362155700346563520219959414822266609886431743244022765016691946524916420466809987199530921747757247500730063754045779461488290595791421275722073185098518062801639098522316430587393735014715370418409259415765501561612270870034996084306862602366649776758112362501777575349310161869393581071135320204480452266424166750964877309802541156141841027861343995260425480065401403708051718432483537393822332675352874816340529161184972343286092169271933800992528678582709672663739764798051192151513344642683447755532995979001381994916950929260120990036284113351569887894147150494750248331523838889719384616071121061718696498195767813194327881887686690860858379418074132274976889571282289124559055190409234598355621871557985669202466416105167863037219586220811185198713192462997299662523846221014581181452132449554002089962666227909580681034068406417989092652927747285712844313573395580565544928396172577748201763122293596435127276689740417356897956093780404518081998819933373808562432489718066989830772821757742230844829055523245065248574022581214918658481971694655845477467565530031143238216433436545056868777889965945234334003802823432857929836100264462921344811106693845963065025070084708986818411565682992780808914009809900669873681867663202504507053975727620079343936598076642450353491027075187752609337033382803274361096744143740526280983577624576663716984283493936031655465953669392929913393318482144724096177251594113926715750874070553688781772935943592837411158705620970848351005470416131896874177828606418246168995277631843914335396304717018508472522606874665037208161976298072728580723522938847911438255285883028350416340517532600988923434468859522607094581906138122310491105840479723349728742092988726824715720474398642429243977904168322290687476782911411250464837848412774318602589533226204430583185438499810211082623806583953168741717477213509542305917467249371518073810771782457135465980105882037970704074959347796281516669885038780132941229658859002267507672171084160715140841547565916580367531319508477429474851679902377692696664968457714122241476296050470279435878973412275453039483751529006621302315176017890774335637876672828968616203452313018476615719821209250297922988593907812944859386252545301452512162408299855845245307981672173910678475165177418424215528796638363139129733254431168299483959320512411635380926749519455675668717029753091997336564600058965594002389932287956659526921620527066151805813760214196267774017718764684817311270765332507042891939214228274047896577224565592774666719553312466290143796483749046311441859054221829167998624467738578314434046197034953481190702299257878603772877496491568834179771568188821076180142700594191259249351538971737549890585211264347819496325245379032773420287709790232391247055789192577154316918088974782846205735025319691468740203858802761388996100252457067800949280957972734905817112696331979555788757104863097550699461913334049297704450331468818241876360896278330079289814105809326248016234075463196423267043925023297375343670293807948868884547117701557149115613642802028786267741883584579256294198260382361772029257106660116838307161458352297112168052360396828716420409709563281891067979234328954280588332934811667044574745550877667497132070065084410560716615277715561351913672470780047885814478770554292467838733011596875499002093325447167892049987028332652687817705049155443212950062672344764659389071576532998993651578837837585826851726410914012534476503162903898713873763087284548172988226607618423525157304065309920723481568299686532561451981169849626076615193626435268650256141852531144864501223291258875450976145776672816894442038090141293730937084528661517378782939073707584178929935429178117306893835442504135360784914194102895184293851606656085599729558941118532468039727885859539255631780575040627845323864447725568381694827926121106291681195073140542339456441454835458075381066305661179433683559005593445700757989627049841652209189669159724563559642603576479957126541600015574932069243257711955737870896737714664776519210530043920876138565081671996987422688088721751673776687264160565046824746349067073448740863163145250432475988621680653293037474931209153229252598662779269562349917149417515932946481353449009359750940695951836980840696761919574988412648375480068930120828650308177450320434748077738132540511020806760751811057311078105002661985154523987319586591867441556375582846701226791908020013863931217731010533822971730242364826393720034660185960361086200294167499172675092616440954184137362050308912568939455970719900236751046171471480666347557351203732777274912418525916941139066659044422004132072149663353045250456276344935158468494366775936016622291813353241518564366825038570847847746075774879401502748694459925013805635250790184638891433520068114371380536275174778030786724857785978565823632242515421710726348296366566701314136178690208907443513400266943862417057086245826632767570546243732364449612781351619360316938272394736153953712594375436805277611210652760189497203182513848520878455544476359836255723439270595981157698039169349492346481946937427459646757619777487934160977416634748575987213016461070698975714877746887476669740644333556645658603393869644764771472522067271332420417316638666646570605776540138661188451876942323652148711281341777405477761282401681279373701026204243676246419086303311323211720678673934578376130443005325793071506662939942686916200961740493587972488278396467713881463380519154747132469113675033837874880132712238626150968959371868388946214054797820862930495907038620759270776450718584854164040848249984956143309704873077785893961885102251875840371450648245022440693744459388392137590394416661021561366173661351247542922125796784835412318525637022384489107177876370865877976957300003472046361414946532677063171572475682077466149912904154425583244496585550136777512392754649245779967094472624327078207105834436596194653651939727952602495386260997565768190148800983869188783661297397021801572653309359245398857793583853215736027639886131970070344661077449643493212026130940227756918699950692021491892575494856703285958426376311245549029805043958977642158264925953086690564766822517573339968218423918388377590107279529044532913638650437046849824726493844361746647041503409483040231183318831107717900685530605050641349170337444684663148864852178044515606654982703703422205504624791495698618929201924422640304709894255465337230808923371828261969530199622540481223058625413696959292364668347495037891816955170622563140315776178738282187245124517318572206656099059723332380947521428478406555653386925532874390602708178119563419208102380407151096277976456127732385285509734005189368223400032336824574673623912372061524077119793683051453421430146965594825134451746205159248611769842630554875841517639617475859341380184659149783207645450083097195854404923105941806370767661387652280965386119855848244868504686760754385474561790923737911445400466527039621632170274144312209965178801920912866202322825498700489207726634030504429277455221243376955361840912842705388935702497391994816975548254703329721076237326623383972988745639772915169378026600215433794249124634249889337418230369910080870115913550665989036532968834198527779806386782578555956857174159499707520560687215226860466925431698603761990201747962766747458116128426195237798321251668072304182673121521443907125625691174889244794297291057052658036924198095611341400130255706381469835855695124190237561134970018229980970070270529350775229089653095994295262380412399354145716916848410262556274807873428744015650586755525445657426129402404749148995226563824393184024618232274622488587997559411705073551429066173304665759057522472721999855226006301953201971813021864659586821375497508719020158049719486740222481088632202241131555779180358990962278335622588562029503643574140791054493481956787052884366063086649137443351437478074101417031107234540663102194720090717623545686380518374516001413379124978330776436886228679320323275215885676760788426444111452047535483728651117773659472691167398999459806829906649896606101099743614027144960195436882587256116380432393312627324026643248333195040354880139391311727886879342897107570241709260077616964839307053157330591131874540145485149576198744551908965988112230176945454625159428397750033896588556251530269427830763091476548651974348272024813647269907918267281040661424462500556879914633715817364353080988627540581164228399066685509814932670578739130079413142059825656588545274542403219550753177429395693426336624882023446490509911215195872272446675584769222796354602290785154804257299448374251770332796645409826812377299587220266985876611217572945048089048766967194165078461372121353214352709203440780690878269953872556116637405792308276137173919474848909849787116396577945794307055219842008464767784959986536770957607110246446884661834689841081096934053283546272461579078927092101824250092345125804433199849596512273862288602147011822711368962325899905730793743290662833719853636014401271401595793719870748178120281159739493122511463975633169556652995213987033631088698775003168835412086084519308125223468552533195558195366969378604968833459885502559227804972115300772992664797218722487220135484603441221711867426998289656806838442033402259783755699434200446793262980103902593171703005381077107842454169346828353338856359724782946491099671279994271926085454625793800877578163346691496768303104032706596745589312557855333395796290493408794837033
0xb2B31428...8C5AeE0a8
(Small Doge: Deployer)
1 Eth
Nonce: 0
0.549326495 Eth
Nonce: 1
0.450673505
(Ethermine)
1,976.002999529261585093 Eth1,976.453673034261585093 Eth0.450673505

Execution Trace

hToken.60806040( )
pragma solidity ^0.4.17;

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }
        uint256 c = a * b;
        assert(c / a == b);
        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        assert(c >= a);
        return c;
    }
}

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address public owner;

    /**
      * @dev The Ownable constructor sets the original `owner` of the contract to the sender
      * account.
      */
    function Ownable() public {
        owner = msg.sender;
    }

    /**
      * @dev Throws if called by any account other than the owner.
      */
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    /**
    * @dev Allows the current owner to transfer control of the contract to a newOwner.
    * @param newOwner The address to transfer ownership to.
    */
    function transferOwnership(address newOwner) public onlyOwner {
        if (newOwner != address(0)) {
            owner = newOwner;
        }
    }

}

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20Basic {
    uint public _totalSupply;
    function totalSupply() public constant returns (uint);
    function balanceOf(address who) public constant returns (uint);
    function transfer(address to, uint value) public;
    event Transfer(address indexed from, address indexed to, uint value);
}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
    function allowance(address owner, address spender) public constant returns (uint);
    function transferFrom(address from, address to, uint value) public;
    function approve(address spender, uint value) public;
    event Approval(address indexed owner, address indexed spender, uint value);
}

/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is Ownable, ERC20Basic {
    using SafeMath for uint;

    mapping(address => uint) public balances;

    // additional variables for use if transaction fees ever became necessary
    uint public basisPointsRate = 0;
    uint public maximumFee = 0;

    /**
    * @dev Fix for the ERC20 short address attack.
    */
    modifier onlyPayloadSize(uint size) {
        require(!(msg.data.length < size + 4));
        _;
    }

    /**
    * @dev transfer token for a specified address
    * @param _to The address to transfer to.
    * @param _value The amount to be transferred.
    */
    function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) {
        uint fee = (_value.mul(basisPointsRate)).div(10000);
        if (fee > maximumFee) {
            fee = maximumFee;
        }
        uint sendAmount = _value.sub(fee);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(sendAmount);
        if (fee > 0) {
            balances[owner] = balances[owner].add(fee);
            Transfer(msg.sender, owner, fee);
        }
        Transfer(msg.sender, _to, sendAmount);
    }

    /**
    * @dev Gets the balance of the specified address.
    * @param _owner The address to query the the balance of.
    * @return An uint representing the amount owned by the passed address.
    */
    function balanceOf(address _owner) public constant returns (uint balance) {
        return balances[_owner];
    }

}

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * @dev https://github.com/ethereum/EIPs/issues/20
 * @dev Based oncode by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract StandardToken is BasicToken, ERC20 {

    mapping (address => mapping (address => uint)) public allowed;

    uint public constant MAX_UINT = 2**256 - 1;

    /**
    * @dev Transfer tokens from one address to another
    * @param _from address The address which you want to send tokens from
    * @param _to address The address which you want to transfer to
    * @param _value uint the amount of tokens to be transferred
    */
    function transferFrom(address _from, address _to, uint _value) public onlyPayloadSize(3 * 32) {
        var _allowance = allowed[_from][msg.sender];

        // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
        // if (_value > _allowance) throw;

        uint fee = (_value.mul(basisPointsRate)).div(10000);
        if (fee > maximumFee) {
            fee = maximumFee;
        }
        if (_allowance < MAX_UINT) {
            allowed[_from][msg.sender] = _allowance.sub(_value);
        }
        uint sendAmount = _value.sub(fee);
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(sendAmount);
        if (fee > 0) {
            balances[owner] = balances[owner].add(fee);
            Transfer(_from, owner, fee);
        }
        Transfer(_from, _to, sendAmount);
    }

    /**
    * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
    * @param _spender The address which will spend the funds.
    * @param _value The amount of tokens to be spent.
    */
    function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) {

        // To change the approve amount you first have to reduce the addresses`
        //  allowance to zero by calling `approve(_spender, 0)` if it is not
        //  already 0 to mitigate the race condition described here:
        //  https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
        require(!((_value != 0) && (allowed[msg.sender][_spender] != 0)));

        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
    }

    /**
    * @dev Function to check the amount of tokens than an owner allowed to a spender.
    * @param _owner address The address which owns the funds.
    * @param _spender address The address which will spend the funds.
    * @return A uint specifying the amount of tokens still available for the spender.
    */
    function allowance(address _owner, address _spender) public constant returns (uint remaining) {
        return allowed[_owner][_spender];
    }

}


/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is Ownable {
  event Pause();
  event Unpause();

  bool public paused = false;


  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
    require(!paused);
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
    require(paused);
    _;
  }

  /**
   * @dev called by the owner to pause, triggers stopped state
   */
  function pause() onlyOwner whenNotPaused public {
    paused = true;
    Pause();
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() onlyOwner whenPaused public {
    paused = false;
    Unpause();
  }
}

contract BlackList is Ownable, BasicToken {

    /////// Getters to allow the same blacklist to be used also by other contracts (including upgraded CNYT) ///////
    function getBlackListStatus(address _maker) external constant returns (bool) {
        return isBlackListed[_maker];
    }

    function getOwner() external constant returns (address) {
        return owner;
    }

    mapping (address => bool) public isBlackListed;
    
    function addBlackList (address _evilUser) public onlyOwner {
        isBlackListed[_evilUser] = true;
        AddedBlackList(_evilUser);
    }

    function removeBlackList (address _clearedUser) public onlyOwner {
        isBlackListed[_clearedUser] = false;
        RemovedBlackList(_clearedUser);
    }

    function destroyBlackFunds (address _blackListedUser) public onlyOwner {
        require(isBlackListed[_blackListedUser]);
        uint dirtyFunds = balanceOf(_blackListedUser);
        balances[_blackListedUser] = 0;
        _totalSupply -= dirtyFunds;
        DestroyedBlackFunds(_blackListedUser, dirtyFunds);
    }

    event DestroyedBlackFunds(address _blackListedUser, uint _balance);

    event AddedBlackList(address _user);

    event RemovedBlackList(address _user);

}

contract UpgradedStandardToken is StandardToken{
    // those methods are called by the legacy contract
    // and they must ensure msg.sender to be the contract address
    function transferByLegacy(address from, address to, uint value) public;
    function transferFromByLegacy(address sender, address from, address spender, uint value) public;
    function approveByLegacy(address from, address spender, uint value) public;
}

contract hToken is Pausable, StandardToken, BlackList {

    string public name;
    string public symbol;
    uint public decimals;
    address public upgradedAddress;
    bool public deprecated;

    //  The contract can be initialized with a number of tokens
    //  All the tokens are deposited to the owner address
    //
    // @param _balance Initial supply of the contract
    // @param _name Token Name
    // @param _symbol Token symbol
    // @param _decimals Token decimals
    function hToken(uint _initialSupply, string _name, string _symbol, uint _decimals) public {
        _totalSupply = _initialSupply;
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        balances[owner] = _initialSupply;
        deprecated = false;
    }

    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function transfer(address _to, uint _value) public whenNotPaused {
        require(!isBlackListed[msg.sender]);
        if (deprecated) {
            return UpgradedStandardToken(upgradedAddress).transferByLegacy(msg.sender, _to, _value);
        } else {
            return super.transfer(_to, _value);
        }
    }

    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function transferFrom(address _from, address _to, uint _value) public whenNotPaused {
        require(!isBlackListed[_from]);
        if (deprecated) {
            return UpgradedStandardToken(upgradedAddress).transferFromByLegacy(msg.sender, _from, _to, _value);
        } else {
            return super.transferFrom(_from, _to, _value);
        }
    }

    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function balanceOf(address who) public constant returns (uint) {
        if (deprecated) {
            return UpgradedStandardToken(upgradedAddress).balanceOf(who);
        } else {
            return super.balanceOf(who);
        }
    }

    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) {
        if (deprecated) {
            return UpgradedStandardToken(upgradedAddress).approveByLegacy(msg.sender, _spender, _value);
        } else {
            return super.approve(_spender, _value);
        }
    }

    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function allowance(address _owner, address _spender) public constant returns (uint remaining) {
        if (deprecated) {
            return StandardToken(upgradedAddress).allowance(_owner, _spender);
        } else {
            return super.allowance(_owner, _spender);
        }
    }

    // deprecate current contract in favour of a new one
    function deprecate(address _upgradedAddress) public onlyOwner {
        deprecated = true;
        upgradedAddress = _upgradedAddress;
        Deprecate(_upgradedAddress);
    }

    // deprecate current contract if favour of a new one
    function totalSupply() public constant returns (uint) {
        if (deprecated) {
            return StandardToken(upgradedAddress).totalSupply();
        } else {
            return _totalSupply;
        }
    }

    // Issue a new amount of tokens
    // these tokens are deposited into the owner address
    //
    // @param _amount Number of tokens to be issued
    // function issue(uint amount) public onlyOwner {
    //     require(_totalSupply + amount > _totalSupply);
    //     require(balances[owner] + amount > balances[owner]);

    //     balances[owner] += amount;
    //     _totalSupply += amount;
    //     Issue(amount);
    // }

    // Redeem tokens.
    // These tokens are withdrawn from the owner address
    // if the balance must be enough to cover the redeem
    // or the call will fail.
    // @param _amount Number of tokens to be issued
    // function redeem(uint amount) public onlyOwner {
    //     require(_totalSupply >= amount);
    //     require(balances[owner] >= amount);

    //     _totalSupply -= amount;
    //     balances[owner] -= amount;
    //     Redeem(amount);
    // }

    function setParams(uint newBasisPoints, uint newMaxFee) public onlyOwner {
        // Ensure transparency by hardcoding limit beyond which fees can never be added
        require(newBasisPoints < 20);
        require(newMaxFee < 50);

        basisPointsRate = newBasisPoints;
        maximumFee = newMaxFee.mul(10**decimals);

        Params(basisPointsRate, maximumFee);
    }

    // Called when new token are issued
    // event Issue(uint amount);

    // Called when tokens are redeemed
    // event Redeem(uint amount);

    // Called when contract is deprecated
    event Deprecate(address newAddress);

    // Called if contract ever adds fees
    event Params(uint feeBasisPoints, uint maxFee);
}