processor.rs 184 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306
  1. #![cfg(feature = "test-sbf")]
  2. //! Program state processor tests
  3. use {
  4. mollusk_svm::{result::Check, Mollusk},
  5. serial_test::serial,
  6. solana_sdk::{
  7. account::{create_account_for_test, Account as SolanaAccount, ReadableAccount},
  8. account_info::{AccountInfo, IntoAccountInfo},
  9. entrypoint::ProgramResult,
  10. instruction::Instruction,
  11. program_error::ProgramError,
  12. program_option::COption,
  13. program_pack::Pack,
  14. pubkey::Pubkey,
  15. rent::Rent,
  16. sysvar::rent,
  17. },
  18. spl_token::{
  19. error::TokenError,
  20. instruction::{
  21. amount_to_ui_amount, approve, approve_checked, burn, burn_checked, close_account,
  22. freeze_account, get_account_data_size, initialize_account, initialize_account2,
  23. initialize_account3, initialize_immutable_owner, initialize_mint, initialize_mint2,
  24. initialize_multisig, initialize_multisig2, mint_to, mint_to_checked, revoke,
  25. set_authority, sync_native, thaw_account, transfer, transfer_checked,
  26. ui_amount_to_amount, AuthorityType, MAX_SIGNERS,
  27. },
  28. state::{Account, AccountState, Mint, Multisig},
  29. },
  30. std::collections::HashMap,
  31. };
  32. fn do_process_instruction(
  33. instruction: Instruction,
  34. mut accounts: Vec<&mut SolanaAccount>,
  35. checks: &[Check],
  36. ) -> ProgramResult {
  37. // Prepare accounts for mollusk.
  38. let instruction_accounts: Vec<(Pubkey, SolanaAccount)> = instruction
  39. .accounts
  40. .iter()
  41. .zip(&accounts)
  42. .map(|(account_meta, account)| (account_meta.pubkey, (*account).clone()))
  43. .collect();
  44. let mollusk = Mollusk::new(&spl_token::ID, "spl_token");
  45. let result =
  46. mollusk.process_and_validate_instruction(&instruction, &instruction_accounts, checks);
  47. // Update accounts after the instruction is processed.
  48. for (original, (_, updated)) in accounts
  49. .iter_mut()
  50. .zip(result.resulting_accounts.into_iter())
  51. {
  52. original.data = updated.data().to_vec();
  53. original.lamports = updated.lamports();
  54. original.owner = *updated.owner();
  55. }
  56. result
  57. .raw_result
  58. .map_err(|e| ProgramError::try_from(e).unwrap())
  59. }
  60. fn do_process_instruction_dups(
  61. instruction: Instruction,
  62. account_infos: Vec<AccountInfo>,
  63. checks: &[Check],
  64. ) -> ProgramResult {
  65. let mut cached_accounts = HashMap::new();
  66. let mut dedup_accounts = Vec::new();
  67. // Dedup accounts for mollusk.
  68. account_infos.iter().for_each(|account_info| {
  69. if !cached_accounts.contains_key(account_info.key) {
  70. let account = SolanaAccount {
  71. lamports: account_info.lamports(),
  72. data: account_info.try_borrow_data().unwrap().to_vec(),
  73. owner: *account_info.owner,
  74. executable: account_info.executable,
  75. rent_epoch: account_info.rent_epoch,
  76. };
  77. dedup_accounts.push((*account_info.key, account));
  78. cached_accounts.insert(account_info.key, account_info);
  79. }
  80. });
  81. let mollusk = Mollusk::new(&spl_token::ID, "spl_token");
  82. let result = mollusk.process_and_validate_instruction(&instruction, &dedup_accounts, checks);
  83. // Update accounts after the instruction is processed.
  84. result
  85. .resulting_accounts
  86. .into_iter()
  87. .for_each(|(pubkey, account)| {
  88. let account = account.clone();
  89. let account_info = cached_accounts.get(&pubkey).unwrap();
  90. if account.data.is_empty() {
  91. // When the account is closed, the tests expect the data to
  92. // be zeroed.
  93. account_info.try_borrow_mut_data().unwrap().fill(0);
  94. } else {
  95. account_info
  96. .try_borrow_mut_data()
  97. .unwrap()
  98. .copy_from_slice(account.data());
  99. }
  100. **account_info.try_borrow_mut_lamports().unwrap() = account.lamports();
  101. account_info.assign(account.owner());
  102. });
  103. result
  104. .raw_result
  105. .map_err(|e| ProgramError::try_from(e).unwrap())
  106. }
  107. fn rent_sysvar() -> SolanaAccount {
  108. create_account_for_test(&Rent::default())
  109. }
  110. fn mint_minimum_balance() -> u64 {
  111. Rent::default().minimum_balance(Mint::get_packed_len())
  112. }
  113. fn account_minimum_balance() -> u64 {
  114. Rent::default().minimum_balance(Account::get_packed_len())
  115. }
  116. fn multisig_minimum_balance() -> u64 {
  117. Rent::default().minimum_balance(Multisig::get_packed_len())
  118. }
  119. #[test]
  120. fn test_initialize_mint() {
  121. let program_id = spl_token::id();
  122. let owner_key = Pubkey::new_unique();
  123. let mint_key = Pubkey::new_unique();
  124. let mut mint_account = SolanaAccount::new(42, Mint::get_packed_len(), &program_id);
  125. let mint2_key = Pubkey::new_unique();
  126. let mut mint2_account =
  127. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  128. let mut rent_sysvar = rent_sysvar();
  129. // mint is not rent exempt
  130. assert_eq!(
  131. Err(TokenError::NotRentExempt.into()),
  132. do_process_instruction(
  133. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  134. vec![&mut mint_account, &mut rent_sysvar],
  135. &[Check::err(TokenError::NotRentExempt.into())],
  136. )
  137. );
  138. mint_account.lamports = mint_minimum_balance();
  139. // create new mint
  140. do_process_instruction(
  141. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  142. vec![&mut mint_account, &mut rent_sysvar],
  143. &[Check::success()],
  144. )
  145. .unwrap();
  146. // create twice
  147. assert_eq!(
  148. Err(TokenError::AlreadyInUse.into()),
  149. do_process_instruction(
  150. initialize_mint(&program_id, &mint_key, &owner_key, None, 2,).unwrap(),
  151. vec![&mut mint_account, &mut rent_sysvar],
  152. &[Check::err(TokenError::AlreadyInUse.into())],
  153. )
  154. );
  155. // create another mint that can freeze
  156. do_process_instruction(
  157. initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
  158. vec![&mut mint2_account, &mut rent_sysvar],
  159. &[
  160. Check::success(),
  161. // freeze authority is set
  162. Check::account(&mint2_key)
  163. .data_slice(46, &[1, 0, 0, 0])
  164. .build(),
  165. // freeze authority matches owner
  166. Check::account(&mint2_key)
  167. .data_slice(50, owner_key.as_ref())
  168. .build(),
  169. ],
  170. )
  171. .unwrap();
  172. let mint = Mint::unpack_unchecked(&mint2_account.data).unwrap();
  173. assert_eq!(mint.freeze_authority, COption::Some(owner_key));
  174. }
  175. #[test]
  176. fn test_initialize_mint2() {
  177. let program_id = spl_token::id();
  178. let owner_key = Pubkey::new_unique();
  179. let mint_key = Pubkey::new_unique();
  180. let mut mint_account = SolanaAccount::new(42, Mint::get_packed_len(), &program_id);
  181. let mint2_key = Pubkey::new_unique();
  182. let mut mint2_account =
  183. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  184. // mint is not rent exempt
  185. assert_eq!(
  186. Err(TokenError::NotRentExempt.into()),
  187. do_process_instruction(
  188. initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  189. vec![&mut mint_account],
  190. &[Check::err(TokenError::NotRentExempt.into())],
  191. )
  192. );
  193. mint_account.lamports = mint_minimum_balance();
  194. // create new mint
  195. do_process_instruction(
  196. initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  197. vec![&mut mint_account],
  198. &[Check::success()],
  199. )
  200. .unwrap();
  201. // create twice
  202. assert_eq!(
  203. Err(TokenError::AlreadyInUse.into()),
  204. do_process_instruction(
  205. initialize_mint2(&program_id, &mint_key, &owner_key, None, 2,).unwrap(),
  206. vec![&mut mint_account],
  207. &[Check::err(TokenError::AlreadyInUse.into())],
  208. )
  209. );
  210. // create another mint that can freeze
  211. do_process_instruction(
  212. initialize_mint2(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
  213. vec![&mut mint2_account],
  214. &[
  215. Check::success(),
  216. // freeze authority is set
  217. Check::account(&mint2_key)
  218. .data_slice(46, &[1, 0, 0, 0])
  219. .build(),
  220. // freeze authority matches owner
  221. Check::account(&mint2_key)
  222. .data_slice(50, owner_key.as_ref())
  223. .build(),
  224. ],
  225. )
  226. .unwrap();
  227. let mint = Mint::unpack_unchecked(&mint2_account.data).unwrap();
  228. assert_eq!(mint.freeze_authority, COption::Some(owner_key));
  229. }
  230. #[test]
  231. fn test_initialize_mint_account() {
  232. let program_id = spl_token::id();
  233. let account_key = Pubkey::new_unique();
  234. let mut account_account = SolanaAccount::new(42, Account::get_packed_len(), &program_id);
  235. let owner_key = Pubkey::new_unique();
  236. let mut owner_account = SolanaAccount::default();
  237. let mint_key = Pubkey::new_unique();
  238. let mut mint_account =
  239. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  240. let mut rent_sysvar = rent_sysvar();
  241. // account is not rent exempt
  242. assert_eq!(
  243. Err(TokenError::NotRentExempt.into()),
  244. do_process_instruction(
  245. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  246. vec![
  247. &mut account_account,
  248. &mut mint_account,
  249. &mut owner_account,
  250. &mut rent_sysvar
  251. ],
  252. &[Check::err(TokenError::NotRentExempt.into())],
  253. )
  254. );
  255. account_account.lamports = account_minimum_balance();
  256. // mint is not valid (not initialized)
  257. assert_eq!(
  258. Err(TokenError::InvalidMint.into()),
  259. do_process_instruction(
  260. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  261. vec![
  262. &mut account_account,
  263. &mut mint_account,
  264. &mut owner_account,
  265. &mut rent_sysvar
  266. ],
  267. &[Check::err(TokenError::InvalidMint.into())],
  268. )
  269. );
  270. // create mint
  271. do_process_instruction(
  272. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  273. vec![&mut mint_account, &mut rent_sysvar],
  274. &[Check::success()],
  275. )
  276. .unwrap();
  277. // mint not owned by program
  278. let not_program_id = Pubkey::new_unique();
  279. mint_account.owner = not_program_id;
  280. assert_eq!(
  281. Err(ProgramError::IncorrectProgramId),
  282. do_process_instruction(
  283. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  284. vec![
  285. &mut account_account,
  286. &mut mint_account,
  287. &mut owner_account,
  288. &mut rent_sysvar
  289. ],
  290. &[Check::err(ProgramError::IncorrectProgramId)],
  291. )
  292. );
  293. mint_account.owner = program_id;
  294. // create account
  295. do_process_instruction(
  296. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  297. vec![
  298. &mut account_account,
  299. &mut mint_account,
  300. &mut owner_account,
  301. &mut rent_sysvar,
  302. ],
  303. &[Check::success()],
  304. )
  305. .unwrap();
  306. // create twice
  307. assert_eq!(
  308. Err(TokenError::AlreadyInUse.into()),
  309. do_process_instruction(
  310. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  311. vec![
  312. &mut account_account,
  313. &mut mint_account,
  314. &mut owner_account,
  315. &mut rent_sysvar
  316. ],
  317. &[Check::err(TokenError::AlreadyInUse.into())],
  318. )
  319. );
  320. }
  321. #[test]
  322. fn test_transfer_dups() {
  323. let program_id = spl_token::id();
  324. let account1_key = Pubkey::new_unique();
  325. let mut account1_account = SolanaAccount::new(
  326. account_minimum_balance(),
  327. Account::get_packed_len(),
  328. &program_id,
  329. );
  330. let mut account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
  331. let account2_key = Pubkey::new_unique();
  332. let mut account2_account = SolanaAccount::new(
  333. account_minimum_balance(),
  334. Account::get_packed_len(),
  335. &program_id,
  336. );
  337. let mut account2_info: AccountInfo = (&account2_key, false, &mut account2_account).into();
  338. let account3_key = Pubkey::new_unique();
  339. let mut account3_account = SolanaAccount::new(
  340. account_minimum_balance(),
  341. Account::get_packed_len(),
  342. &program_id,
  343. );
  344. let account3_info: AccountInfo = (&account3_key, false, &mut account3_account).into();
  345. let account4_key = Pubkey::new_unique();
  346. let mut account4_account = SolanaAccount::new(
  347. account_minimum_balance(),
  348. Account::get_packed_len(),
  349. &program_id,
  350. );
  351. let account4_info: AccountInfo = (&account4_key, true, &mut account4_account).into();
  352. let multisig_key = Pubkey::new_unique();
  353. let mut multisig_account = SolanaAccount::new(
  354. multisig_minimum_balance(),
  355. Multisig::get_packed_len(),
  356. &program_id,
  357. );
  358. let multisig_info: AccountInfo = (&multisig_key, true, &mut multisig_account).into();
  359. let owner_key = Pubkey::new_unique();
  360. let mut owner_account = SolanaAccount::default();
  361. let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
  362. let mint_key = Pubkey::new_unique();
  363. let mut mint_account =
  364. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  365. let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
  366. let rent_key = rent::id();
  367. let mut rent_sysvar = rent_sysvar();
  368. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  369. // create mint
  370. do_process_instruction_dups(
  371. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  372. vec![mint_info.clone(), rent_info.clone()],
  373. &[Check::success()],
  374. )
  375. .unwrap();
  376. // create account
  377. do_process_instruction_dups(
  378. initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
  379. vec![
  380. account1_info.clone(),
  381. mint_info.clone(),
  382. account1_info.clone(),
  383. rent_info.clone(),
  384. ],
  385. &[Check::success()],
  386. )
  387. .unwrap();
  388. // create another account
  389. do_process_instruction_dups(
  390. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  391. vec![
  392. account2_info.clone(),
  393. mint_info.clone(),
  394. owner_info.clone(),
  395. rent_info.clone(),
  396. ],
  397. &[Check::success()],
  398. )
  399. .unwrap();
  400. // mint to account
  401. do_process_instruction_dups(
  402. mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
  403. vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
  404. &[Check::success()],
  405. )
  406. .unwrap();
  407. // source-owner transfer
  408. do_process_instruction_dups(
  409. transfer(
  410. &program_id,
  411. &account1_key,
  412. &account2_key,
  413. &account1_key,
  414. &[],
  415. 500,
  416. )
  417. .unwrap(),
  418. vec![
  419. account1_info.clone(),
  420. account2_info.clone(),
  421. account1_info.clone(),
  422. ],
  423. &[Check::success()],
  424. )
  425. .unwrap();
  426. // source-owner TransferChecked
  427. do_process_instruction_dups(
  428. transfer_checked(
  429. &program_id,
  430. &account1_key,
  431. &mint_key,
  432. &account2_key,
  433. &account1_key,
  434. &[],
  435. 500,
  436. 2,
  437. )
  438. .unwrap(),
  439. vec![
  440. account1_info.clone(),
  441. mint_info.clone(),
  442. account2_info.clone(),
  443. account1_info.clone(),
  444. ],
  445. &[Check::success()],
  446. )
  447. .unwrap();
  448. // source-delegate transfer
  449. let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
  450. account.amount = 1000;
  451. account.delegated_amount = 1000;
  452. account.delegate = COption::Some(account1_key);
  453. account.owner = owner_key;
  454. Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
  455. do_process_instruction_dups(
  456. transfer(
  457. &program_id,
  458. &account1_key,
  459. &account2_key,
  460. &account1_key,
  461. &[],
  462. 500,
  463. )
  464. .unwrap(),
  465. vec![
  466. account1_info.clone(),
  467. account2_info.clone(),
  468. account1_info.clone(),
  469. ],
  470. &[Check::success()],
  471. )
  472. .unwrap();
  473. // source-delegate TransferChecked
  474. do_process_instruction_dups(
  475. transfer_checked(
  476. &program_id,
  477. &account1_key,
  478. &mint_key,
  479. &account2_key,
  480. &account1_key,
  481. &[],
  482. 500,
  483. 2,
  484. )
  485. .unwrap(),
  486. vec![
  487. account1_info.clone(),
  488. mint_info.clone(),
  489. account2_info.clone(),
  490. account1_info.clone(),
  491. ],
  492. &[Check::success()],
  493. )
  494. .unwrap();
  495. // test destination-owner transfer
  496. do_process_instruction_dups(
  497. initialize_account(&program_id, &account3_key, &mint_key, &account2_key).unwrap(),
  498. vec![
  499. account3_info.clone(),
  500. mint_info.clone(),
  501. account2_info.clone(),
  502. rent_info.clone(),
  503. ],
  504. &[Check::success()],
  505. )
  506. .unwrap();
  507. do_process_instruction_dups(
  508. mint_to(&program_id, &mint_key, &account3_key, &owner_key, &[], 1000).unwrap(),
  509. vec![mint_info.clone(), account3_info.clone(), owner_info.clone()],
  510. &[Check::success()],
  511. )
  512. .unwrap();
  513. account1_info.is_signer = false;
  514. account2_info.is_signer = true;
  515. do_process_instruction_dups(
  516. transfer(
  517. &program_id,
  518. &account3_key,
  519. &account2_key,
  520. &account2_key,
  521. &[],
  522. 500,
  523. )
  524. .unwrap(),
  525. vec![
  526. account3_info.clone(),
  527. account2_info.clone(),
  528. account2_info.clone(),
  529. ],
  530. &[Check::success()],
  531. )
  532. .unwrap();
  533. // destination-owner TransferChecked
  534. do_process_instruction_dups(
  535. transfer_checked(
  536. &program_id,
  537. &account3_key,
  538. &mint_key,
  539. &account2_key,
  540. &account2_key,
  541. &[],
  542. 500,
  543. 2,
  544. )
  545. .unwrap(),
  546. vec![
  547. account3_info.clone(),
  548. mint_info.clone(),
  549. account2_info.clone(),
  550. account2_info.clone(),
  551. ],
  552. &[Check::success()],
  553. )
  554. .unwrap();
  555. // test source-multisig signer
  556. do_process_instruction_dups(
  557. initialize_multisig(&program_id, &multisig_key, &[&account4_key], 1).unwrap(),
  558. vec![
  559. multisig_info.clone(),
  560. rent_info.clone(),
  561. account4_info.clone(),
  562. ],
  563. &[Check::success()],
  564. )
  565. .unwrap();
  566. do_process_instruction_dups(
  567. initialize_account(&program_id, &account4_key, &mint_key, &multisig_key).unwrap(),
  568. vec![
  569. account4_info.clone(),
  570. mint_info.clone(),
  571. multisig_info.clone(),
  572. rent_info.clone(),
  573. ],
  574. &[Check::success()],
  575. )
  576. .unwrap();
  577. do_process_instruction_dups(
  578. mint_to(&program_id, &mint_key, &account4_key, &owner_key, &[], 1000).unwrap(),
  579. vec![mint_info.clone(), account4_info.clone(), owner_info.clone()],
  580. &[Check::success()],
  581. )
  582. .unwrap();
  583. // source-multisig-signer transfer
  584. do_process_instruction_dups(
  585. transfer(
  586. &program_id,
  587. &account4_key,
  588. &account2_key,
  589. &multisig_key,
  590. &[&account4_key],
  591. 500,
  592. )
  593. .unwrap(),
  594. vec![
  595. account4_info.clone(),
  596. account2_info.clone(),
  597. multisig_info.clone(),
  598. account4_info.clone(),
  599. ],
  600. &[Check::success()],
  601. )
  602. .unwrap();
  603. // source-multisig-signer TransferChecked
  604. do_process_instruction_dups(
  605. transfer_checked(
  606. &program_id,
  607. &account4_key,
  608. &mint_key,
  609. &account2_key,
  610. &multisig_key,
  611. &[&account4_key],
  612. 500,
  613. 2,
  614. )
  615. .unwrap(),
  616. vec![
  617. account4_info.clone(),
  618. mint_info.clone(),
  619. account2_info.clone(),
  620. multisig_info.clone(),
  621. account4_info.clone(),
  622. ],
  623. &[Check::success()],
  624. )
  625. .unwrap();
  626. }
  627. #[test]
  628. fn test_transfer() {
  629. let program_id = spl_token::id();
  630. let account_key = Pubkey::new_unique();
  631. let mut account_account = SolanaAccount::new(
  632. account_minimum_balance(),
  633. Account::get_packed_len(),
  634. &program_id,
  635. );
  636. let account2_key = Pubkey::new_unique();
  637. let mut account2_account = SolanaAccount::new(
  638. account_minimum_balance(),
  639. Account::get_packed_len(),
  640. &program_id,
  641. );
  642. let account3_key = Pubkey::new_unique();
  643. let mut account3_account = SolanaAccount::new(
  644. account_minimum_balance(),
  645. Account::get_packed_len(),
  646. &program_id,
  647. );
  648. let delegate_key = Pubkey::new_unique();
  649. let mut delegate_account = SolanaAccount::default();
  650. let mismatch_key = Pubkey::new_unique();
  651. let mut mismatch_account = SolanaAccount::new(
  652. account_minimum_balance(),
  653. Account::get_packed_len(),
  654. &program_id,
  655. );
  656. let owner_key = Pubkey::new_unique();
  657. let mut owner_account = SolanaAccount::default();
  658. let owner2_key = Pubkey::new_unique();
  659. let mut owner2_account = SolanaAccount::default();
  660. let mint_key = Pubkey::new_unique();
  661. let mut mint_account =
  662. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  663. let mint2_key = Pubkey::new_unique();
  664. let mut rent_sysvar = rent_sysvar();
  665. // create mint
  666. do_process_instruction(
  667. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  668. vec![&mut mint_account, &mut rent_sysvar],
  669. &[Check::success()],
  670. )
  671. .unwrap();
  672. // create account
  673. do_process_instruction(
  674. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  675. vec![
  676. &mut account_account,
  677. &mut mint_account,
  678. &mut owner_account,
  679. &mut rent_sysvar,
  680. ],
  681. &[Check::success()],
  682. )
  683. .unwrap();
  684. // create another account
  685. do_process_instruction(
  686. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  687. vec![
  688. &mut account2_account,
  689. &mut mint_account,
  690. &mut owner_account,
  691. &mut rent_sysvar,
  692. ],
  693. &[Check::success()],
  694. )
  695. .unwrap();
  696. // create another account
  697. do_process_instruction(
  698. initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
  699. vec![
  700. &mut account3_account,
  701. &mut mint_account,
  702. &mut owner_account,
  703. &mut rent_sysvar,
  704. ],
  705. &[Check::success()],
  706. )
  707. .unwrap();
  708. // create mismatch account
  709. do_process_instruction(
  710. initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
  711. vec![
  712. &mut mismatch_account,
  713. &mut mint_account,
  714. &mut owner_account,
  715. &mut rent_sysvar,
  716. ],
  717. &[Check::success()],
  718. )
  719. .unwrap();
  720. let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
  721. account.mint = mint2_key;
  722. Account::pack(account, &mut mismatch_account.data).unwrap();
  723. // mint to account
  724. do_process_instruction(
  725. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  726. vec![&mut mint_account, &mut account_account, &mut owner_account],
  727. &[Check::success()],
  728. )
  729. .unwrap();
  730. // missing signer
  731. let mut instruction = transfer(
  732. &program_id,
  733. &account_key,
  734. &account2_key,
  735. &owner_key,
  736. &[],
  737. 1000,
  738. )
  739. .unwrap();
  740. instruction.accounts[2].is_signer = false;
  741. assert_eq!(
  742. Err(ProgramError::MissingRequiredSignature),
  743. do_process_instruction(
  744. instruction,
  745. vec![
  746. &mut account_account,
  747. &mut account2_account,
  748. &mut owner_account,
  749. ],
  750. &[Check::err(ProgramError::MissingRequiredSignature)],
  751. )
  752. );
  753. // mismatch mint
  754. assert_eq!(
  755. Err(TokenError::MintMismatch.into()),
  756. do_process_instruction(
  757. transfer(
  758. &program_id,
  759. &account_key,
  760. &mismatch_key,
  761. &owner_key,
  762. &[],
  763. 1000
  764. )
  765. .unwrap(),
  766. vec![
  767. &mut account_account,
  768. &mut mismatch_account,
  769. &mut owner_account,
  770. ],
  771. &[Check::err(TokenError::MintMismatch.into())],
  772. )
  773. );
  774. // missing owner
  775. assert_eq!(
  776. Err(TokenError::OwnerMismatch.into()),
  777. do_process_instruction(
  778. transfer(
  779. &program_id,
  780. &account_key,
  781. &account2_key,
  782. &owner2_key,
  783. &[],
  784. 1000
  785. )
  786. .unwrap(),
  787. vec![
  788. &mut account_account,
  789. &mut account2_account,
  790. &mut owner2_account,
  791. ],
  792. &[Check::err(TokenError::OwnerMismatch.into())],
  793. )
  794. );
  795. // account not owned by program
  796. let not_program_id = Pubkey::new_unique();
  797. account_account.owner = not_program_id;
  798. assert_eq!(
  799. Err(ProgramError::IncorrectProgramId),
  800. do_process_instruction(
  801. transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 0,).unwrap(),
  802. vec![
  803. &mut account_account,
  804. &mut account2_account,
  805. &mut owner2_account,
  806. ],
  807. &[Check::err(ProgramError::IncorrectProgramId)],
  808. )
  809. );
  810. account_account.owner = program_id;
  811. // account 2 not owned by program
  812. let not_program_id = Pubkey::new_unique();
  813. account2_account.owner = not_program_id;
  814. assert_eq!(
  815. Err(ProgramError::IncorrectProgramId),
  816. do_process_instruction(
  817. transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 0,).unwrap(),
  818. vec![
  819. &mut account_account,
  820. &mut account2_account,
  821. &mut owner2_account,
  822. ],
  823. &[Check::err(ProgramError::IncorrectProgramId)],
  824. )
  825. );
  826. account2_account.owner = program_id;
  827. // transfer
  828. do_process_instruction(
  829. transfer(
  830. &program_id,
  831. &account_key,
  832. &account2_key,
  833. &owner_key,
  834. &[],
  835. 1000,
  836. )
  837. .unwrap(),
  838. vec![
  839. &mut account_account,
  840. &mut account2_account,
  841. &mut owner_account,
  842. ],
  843. &[Check::success()],
  844. )
  845. .unwrap();
  846. // insufficient funds
  847. assert_eq!(
  848. Err(TokenError::InsufficientFunds.into()),
  849. do_process_instruction(
  850. transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 1).unwrap(),
  851. vec![
  852. &mut account_account,
  853. &mut account2_account,
  854. &mut owner_account,
  855. ],
  856. &[Check::err(TokenError::InsufficientFunds.into())],
  857. )
  858. );
  859. // transfer half back
  860. do_process_instruction(
  861. transfer(
  862. &program_id,
  863. &account2_key,
  864. &account_key,
  865. &owner_key,
  866. &[],
  867. 500,
  868. )
  869. .unwrap(),
  870. vec![
  871. &mut account2_account,
  872. &mut account_account,
  873. &mut owner_account,
  874. ],
  875. &[Check::success()],
  876. )
  877. .unwrap();
  878. // incorrect decimals
  879. assert_eq!(
  880. Err(TokenError::MintDecimalsMismatch.into()),
  881. do_process_instruction(
  882. transfer_checked(
  883. &program_id,
  884. &account2_key,
  885. &mint_key,
  886. &account_key,
  887. &owner_key,
  888. &[],
  889. 1,
  890. 10 // <-- incorrect decimals
  891. )
  892. .unwrap(),
  893. vec![
  894. &mut account2_account,
  895. &mut mint_account,
  896. &mut account_account,
  897. &mut owner_account,
  898. ],
  899. &[Check::err(TokenError::MintDecimalsMismatch.into())],
  900. )
  901. );
  902. // incorrect mint
  903. assert_eq!(
  904. Err(TokenError::MintMismatch.into()),
  905. do_process_instruction(
  906. transfer_checked(
  907. &program_id,
  908. &account2_key,
  909. &account3_key, // <-- incorrect mint
  910. &account_key,
  911. &owner_key,
  912. &[],
  913. 1,
  914. 2
  915. )
  916. .unwrap(),
  917. vec![
  918. &mut account2_account,
  919. &mut account3_account, // <-- incorrect mint
  920. &mut account_account,
  921. &mut owner_account,
  922. ],
  923. &[Check::err(TokenError::MintMismatch.into())],
  924. )
  925. );
  926. // transfer rest with explicit decimals
  927. do_process_instruction(
  928. transfer_checked(
  929. &program_id,
  930. &account2_key,
  931. &mint_key,
  932. &account_key,
  933. &owner_key,
  934. &[],
  935. 500,
  936. 2,
  937. )
  938. .unwrap(),
  939. vec![
  940. &mut account2_account,
  941. &mut mint_account,
  942. &mut account_account,
  943. &mut owner_account,
  944. ],
  945. &[Check::success()],
  946. )
  947. .unwrap();
  948. // insufficient funds
  949. assert_eq!(
  950. Err(TokenError::InsufficientFunds.into()),
  951. do_process_instruction(
  952. transfer(&program_id, &account2_key, &account_key, &owner_key, &[], 1).unwrap(),
  953. vec![
  954. &mut account2_account,
  955. &mut account_account,
  956. &mut owner_account,
  957. ],
  958. &[Check::err(TokenError::InsufficientFunds.into())],
  959. )
  960. );
  961. // approve delegate
  962. do_process_instruction(
  963. approve(
  964. &program_id,
  965. &account_key,
  966. &delegate_key,
  967. &owner_key,
  968. &[],
  969. 100,
  970. )
  971. .unwrap(),
  972. vec![
  973. &mut account_account,
  974. &mut delegate_account,
  975. &mut owner_account,
  976. ],
  977. &[Check::success()],
  978. )
  979. .unwrap();
  980. // not a delegate of source account
  981. assert_eq!(
  982. Err(TokenError::OwnerMismatch.into()),
  983. do_process_instruction(
  984. transfer(
  985. &program_id,
  986. &account_key,
  987. &account2_key,
  988. &owner2_key, // <-- incorrect owner or delegate
  989. &[],
  990. 1,
  991. )
  992. .unwrap(),
  993. vec![
  994. &mut account_account,
  995. &mut account2_account,
  996. &mut owner2_account,
  997. ],
  998. &[Check::err(TokenError::OwnerMismatch.into())],
  999. )
  1000. );
  1001. // insufficient funds approved via delegate
  1002. assert_eq!(
  1003. Err(TokenError::InsufficientFunds.into()),
  1004. do_process_instruction(
  1005. transfer(
  1006. &program_id,
  1007. &account_key,
  1008. &account2_key,
  1009. &delegate_key,
  1010. &[],
  1011. 101
  1012. )
  1013. .unwrap(),
  1014. vec![
  1015. &mut account_account,
  1016. &mut account2_account,
  1017. &mut delegate_account,
  1018. ],
  1019. &[Check::err(TokenError::InsufficientFunds.into())],
  1020. )
  1021. );
  1022. // transfer via delegate
  1023. do_process_instruction(
  1024. transfer(
  1025. &program_id,
  1026. &account_key,
  1027. &account2_key,
  1028. &delegate_key,
  1029. &[],
  1030. 100,
  1031. )
  1032. .unwrap(),
  1033. vec![
  1034. &mut account_account,
  1035. &mut account2_account,
  1036. &mut delegate_account,
  1037. ],
  1038. &[Check::success()],
  1039. )
  1040. .unwrap();
  1041. // insufficient funds approved via delegate
  1042. assert_eq!(
  1043. Err(TokenError::OwnerMismatch.into()),
  1044. do_process_instruction(
  1045. transfer(
  1046. &program_id,
  1047. &account_key,
  1048. &account2_key,
  1049. &delegate_key,
  1050. &[],
  1051. 1
  1052. )
  1053. .unwrap(),
  1054. vec![
  1055. &mut account_account,
  1056. &mut account2_account,
  1057. &mut delegate_account,
  1058. ],
  1059. &[Check::err(TokenError::OwnerMismatch.into())],
  1060. )
  1061. );
  1062. // transfer rest
  1063. do_process_instruction(
  1064. transfer(
  1065. &program_id,
  1066. &account_key,
  1067. &account2_key,
  1068. &owner_key,
  1069. &[],
  1070. 900,
  1071. )
  1072. .unwrap(),
  1073. vec![
  1074. &mut account_account,
  1075. &mut account2_account,
  1076. &mut owner_account,
  1077. ],
  1078. &[Check::success()],
  1079. )
  1080. .unwrap();
  1081. // approve delegate
  1082. do_process_instruction(
  1083. approve(
  1084. &program_id,
  1085. &account_key,
  1086. &delegate_key,
  1087. &owner_key,
  1088. &[],
  1089. 100,
  1090. )
  1091. .unwrap(),
  1092. vec![
  1093. &mut account_account,
  1094. &mut delegate_account,
  1095. &mut owner_account,
  1096. ],
  1097. &[Check::success()],
  1098. )
  1099. .unwrap();
  1100. // insufficient funds in source account via delegate
  1101. assert_eq!(
  1102. Err(TokenError::InsufficientFunds.into()),
  1103. do_process_instruction(
  1104. transfer(
  1105. &program_id,
  1106. &account_key,
  1107. &account2_key,
  1108. &delegate_key,
  1109. &[],
  1110. 100
  1111. )
  1112. .unwrap(),
  1113. vec![
  1114. &mut account_account,
  1115. &mut account2_account,
  1116. &mut delegate_account,
  1117. ],
  1118. &[Check::err(TokenError::InsufficientFunds.into())],
  1119. )
  1120. );
  1121. }
  1122. #[test]
  1123. fn test_self_transfer() {
  1124. let program_id = spl_token::id();
  1125. let account_key = Pubkey::new_unique();
  1126. let mut account_account = SolanaAccount::new(
  1127. account_minimum_balance(),
  1128. Account::get_packed_len(),
  1129. &program_id,
  1130. );
  1131. let account2_key = Pubkey::new_unique();
  1132. let mut account2_account = SolanaAccount::new(
  1133. account_minimum_balance(),
  1134. Account::get_packed_len(),
  1135. &program_id,
  1136. );
  1137. let account3_key = Pubkey::new_unique();
  1138. let mut account3_account = SolanaAccount::new(
  1139. account_minimum_balance(),
  1140. Account::get_packed_len(),
  1141. &program_id,
  1142. );
  1143. let delegate_key = Pubkey::new_unique();
  1144. let mut delegate_account = SolanaAccount::default();
  1145. let owner_key = Pubkey::new_unique();
  1146. let mut owner_account = SolanaAccount::default();
  1147. let owner2_key = Pubkey::new_unique();
  1148. let mut owner2_account = SolanaAccount::default();
  1149. let mint_key = Pubkey::new_unique();
  1150. let mut mint_account =
  1151. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  1152. let mut rent_sysvar = rent_sysvar();
  1153. // create mint
  1154. do_process_instruction(
  1155. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  1156. vec![&mut mint_account, &mut rent_sysvar],
  1157. &[Check::success()],
  1158. )
  1159. .unwrap();
  1160. // create account
  1161. do_process_instruction(
  1162. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  1163. vec![
  1164. &mut account_account,
  1165. &mut mint_account,
  1166. &mut owner_account,
  1167. &mut rent_sysvar,
  1168. ],
  1169. &[Check::success()],
  1170. )
  1171. .unwrap();
  1172. // create another account
  1173. do_process_instruction(
  1174. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  1175. vec![
  1176. &mut account2_account,
  1177. &mut mint_account,
  1178. &mut owner_account,
  1179. &mut rent_sysvar,
  1180. ],
  1181. &[Check::success()],
  1182. )
  1183. .unwrap();
  1184. // create another account
  1185. do_process_instruction(
  1186. initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
  1187. vec![
  1188. &mut account3_account,
  1189. &mut mint_account,
  1190. &mut owner_account,
  1191. &mut rent_sysvar,
  1192. ],
  1193. &[Check::success()],
  1194. )
  1195. .unwrap();
  1196. // mint to account
  1197. do_process_instruction(
  1198. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  1199. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1200. &[Check::success()],
  1201. )
  1202. .unwrap();
  1203. let account_info = (&account_key, false, &mut account_account).into_account_info();
  1204. let account3_info = (&account3_key, false, &mut account3_account).into_account_info();
  1205. let delegate_info = (&delegate_key, true, &mut delegate_account).into_account_info();
  1206. let owner_info = (&owner_key, true, &mut owner_account).into_account_info();
  1207. let owner2_info = (&owner2_key, true, &mut owner2_account).into_account_info();
  1208. let mint_info = (&mint_key, false, &mut mint_account).into_account_info();
  1209. // transfer
  1210. let instruction = transfer(
  1211. &program_id,
  1212. account_info.key,
  1213. account_info.key,
  1214. owner_info.key,
  1215. &[],
  1216. 1000,
  1217. )
  1218. .unwrap();
  1219. assert_eq!(
  1220. Ok(()),
  1221. do_process_instruction_dups(
  1222. instruction,
  1223. vec![
  1224. account_info.clone(),
  1225. account_info.clone(),
  1226. owner_info.clone(),
  1227. ],
  1228. &[
  1229. Check::success(),
  1230. Check::account(account_info.key)
  1231. .data_slice(64, &1000u64.to_le_bytes())
  1232. .build()
  1233. ],
  1234. )
  1235. );
  1236. // no balance change...
  1237. let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
  1238. assert_eq!(account.amount, 1000);
  1239. // transfer checked
  1240. let instruction = transfer_checked(
  1241. &program_id,
  1242. account_info.key,
  1243. mint_info.key,
  1244. account_info.key,
  1245. owner_info.key,
  1246. &[],
  1247. 1000,
  1248. 2,
  1249. )
  1250. .unwrap();
  1251. assert_eq!(
  1252. Ok(()),
  1253. do_process_instruction_dups(
  1254. instruction,
  1255. vec![
  1256. account_info.clone(),
  1257. mint_info.clone(),
  1258. account_info.clone(),
  1259. owner_info.clone(),
  1260. ],
  1261. &[
  1262. Check::success(),
  1263. Check::account(account_info.key)
  1264. .data_slice(64, &1000u64.to_le_bytes())
  1265. .build()
  1266. ],
  1267. )
  1268. );
  1269. // no balance change...
  1270. let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
  1271. assert_eq!(account.amount, 1000);
  1272. // missing signer
  1273. let mut owner_no_sign_info = owner_info.clone();
  1274. let mut instruction = transfer(
  1275. &program_id,
  1276. account_info.key,
  1277. account_info.key,
  1278. owner_no_sign_info.key,
  1279. &[],
  1280. 1000,
  1281. )
  1282. .unwrap();
  1283. instruction.accounts[2].is_signer = false;
  1284. owner_no_sign_info.is_signer = false;
  1285. assert_eq!(
  1286. Err(ProgramError::MissingRequiredSignature),
  1287. do_process_instruction_dups(
  1288. instruction,
  1289. vec![
  1290. account_info.clone(),
  1291. account_info.clone(),
  1292. owner_no_sign_info.clone(),
  1293. ],
  1294. &[Check::err(ProgramError::MissingRequiredSignature)],
  1295. )
  1296. );
  1297. // missing signer checked
  1298. let mut instruction = transfer_checked(
  1299. &program_id,
  1300. account_info.key,
  1301. mint_info.key,
  1302. account_info.key,
  1303. owner_no_sign_info.key,
  1304. &[],
  1305. 1000,
  1306. 2,
  1307. )
  1308. .unwrap();
  1309. instruction.accounts[3].is_signer = false;
  1310. assert_eq!(
  1311. Err(ProgramError::MissingRequiredSignature),
  1312. do_process_instruction_dups(
  1313. instruction,
  1314. vec![
  1315. account_info.clone(),
  1316. mint_info.clone(),
  1317. account_info.clone(),
  1318. owner_no_sign_info,
  1319. ],
  1320. &[Check::err(ProgramError::MissingRequiredSignature)],
  1321. )
  1322. );
  1323. // missing owner
  1324. let instruction = transfer(
  1325. &program_id,
  1326. account_info.key,
  1327. account_info.key,
  1328. owner2_info.key,
  1329. &[],
  1330. 1000,
  1331. )
  1332. .unwrap();
  1333. assert_eq!(
  1334. Err(TokenError::OwnerMismatch.into()),
  1335. do_process_instruction_dups(
  1336. instruction,
  1337. vec![
  1338. account_info.clone(),
  1339. account_info.clone(),
  1340. owner2_info.clone(),
  1341. ],
  1342. &[Check::err(TokenError::OwnerMismatch.into())],
  1343. )
  1344. );
  1345. // missing owner checked
  1346. let instruction = transfer_checked(
  1347. &program_id,
  1348. account_info.key,
  1349. mint_info.key,
  1350. account_info.key,
  1351. owner2_info.key,
  1352. &[],
  1353. 1000,
  1354. 2,
  1355. )
  1356. .unwrap();
  1357. assert_eq!(
  1358. Err(TokenError::OwnerMismatch.into()),
  1359. do_process_instruction_dups(
  1360. instruction,
  1361. vec![
  1362. account_info.clone(),
  1363. mint_info.clone(),
  1364. account_info.clone(),
  1365. owner2_info.clone(),
  1366. ],
  1367. &[Check::err(TokenError::OwnerMismatch.into())],
  1368. )
  1369. );
  1370. // insufficient funds
  1371. let instruction = transfer(
  1372. &program_id,
  1373. account_info.key,
  1374. account_info.key,
  1375. owner_info.key,
  1376. &[],
  1377. 1001,
  1378. )
  1379. .unwrap();
  1380. assert_eq!(
  1381. Err(TokenError::InsufficientFunds.into()),
  1382. do_process_instruction_dups(
  1383. instruction,
  1384. vec![
  1385. account_info.clone(),
  1386. account_info.clone(),
  1387. owner_info.clone(),
  1388. ],
  1389. &[Check::err(TokenError::InsufficientFunds.into())],
  1390. )
  1391. );
  1392. // insufficient funds checked
  1393. let instruction = transfer_checked(
  1394. &program_id,
  1395. account_info.key,
  1396. mint_info.key,
  1397. account_info.key,
  1398. owner_info.key,
  1399. &[],
  1400. 1001,
  1401. 2,
  1402. )
  1403. .unwrap();
  1404. assert_eq!(
  1405. Err(TokenError::InsufficientFunds.into()),
  1406. do_process_instruction_dups(
  1407. instruction,
  1408. vec![
  1409. account_info.clone(),
  1410. mint_info.clone(),
  1411. account_info.clone(),
  1412. owner_info.clone(),
  1413. ],
  1414. &[Check::err(TokenError::InsufficientFunds.into())],
  1415. )
  1416. );
  1417. // incorrect decimals
  1418. let instruction = transfer_checked(
  1419. &program_id,
  1420. account_info.key,
  1421. mint_info.key,
  1422. account_info.key,
  1423. owner_info.key,
  1424. &[],
  1425. 1,
  1426. 10, // <-- incorrect decimals
  1427. )
  1428. .unwrap();
  1429. assert_eq!(
  1430. Err(TokenError::MintDecimalsMismatch.into()),
  1431. do_process_instruction_dups(
  1432. instruction,
  1433. vec![
  1434. account_info.clone(),
  1435. mint_info.clone(),
  1436. account_info.clone(),
  1437. owner_info.clone(),
  1438. ],
  1439. &[Check::err(TokenError::MintDecimalsMismatch.into())],
  1440. )
  1441. );
  1442. // incorrect mint
  1443. let instruction = transfer_checked(
  1444. &program_id,
  1445. account_info.key,
  1446. account3_info.key, // <-- incorrect mint
  1447. account_info.key,
  1448. owner_info.key,
  1449. &[],
  1450. 1,
  1451. 2,
  1452. )
  1453. .unwrap();
  1454. assert_eq!(
  1455. Err(TokenError::MintMismatch.into()),
  1456. do_process_instruction_dups(
  1457. instruction,
  1458. vec![
  1459. account_info.clone(),
  1460. account3_info.clone(), // <-- incorrect mint
  1461. account_info.clone(),
  1462. owner_info.clone(),
  1463. ],
  1464. &[Check::err(TokenError::MintMismatch.into())],
  1465. )
  1466. );
  1467. // approve delegate
  1468. let instruction = approve(
  1469. &program_id,
  1470. account_info.key,
  1471. delegate_info.key,
  1472. owner_info.key,
  1473. &[],
  1474. 100,
  1475. )
  1476. .unwrap();
  1477. do_process_instruction_dups(
  1478. instruction,
  1479. vec![
  1480. account_info.clone(),
  1481. delegate_info.clone(),
  1482. owner_info.clone(),
  1483. ],
  1484. &[Check::success()],
  1485. )
  1486. .unwrap();
  1487. // delegate transfer
  1488. let instruction = transfer(
  1489. &program_id,
  1490. account_info.key,
  1491. account_info.key,
  1492. delegate_info.key,
  1493. &[],
  1494. 100,
  1495. )
  1496. .unwrap();
  1497. assert_eq!(
  1498. Ok(()),
  1499. do_process_instruction_dups(
  1500. instruction,
  1501. vec![
  1502. account_info.clone(),
  1503. account_info.clone(),
  1504. delegate_info.clone(),
  1505. ],
  1506. &[
  1507. Check::success(),
  1508. Check::account(account_info.key)
  1509. .data_slice(64, &1000u64.to_le_bytes())
  1510. .build(),
  1511. Check::account(&account_key)
  1512. .data_slice(121, &100u64.to_le_bytes())
  1513. .build(),
  1514. ],
  1515. )
  1516. );
  1517. // no balance change...
  1518. let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
  1519. assert_eq!(account.amount, 1000);
  1520. assert_eq!(account.delegated_amount, 100);
  1521. // delegate transfer checked
  1522. let instruction = transfer_checked(
  1523. &program_id,
  1524. account_info.key,
  1525. mint_info.key,
  1526. account_info.key,
  1527. delegate_info.key,
  1528. &[],
  1529. 100,
  1530. 2,
  1531. )
  1532. .unwrap();
  1533. assert_eq!(
  1534. Ok(()),
  1535. do_process_instruction_dups(
  1536. instruction,
  1537. vec![
  1538. account_info.clone(),
  1539. mint_info.clone(),
  1540. account_info.clone(),
  1541. delegate_info.clone(),
  1542. ],
  1543. &[
  1544. Check::success(),
  1545. Check::account(account_info.key)
  1546. .data_slice(64, &1000u64.to_le_bytes())
  1547. .build(),
  1548. Check::account(&account_key)
  1549. .data_slice(121, &100u64.to_le_bytes())
  1550. .build(),
  1551. ],
  1552. )
  1553. );
  1554. // no balance change...
  1555. let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
  1556. assert_eq!(account.amount, 1000);
  1557. assert_eq!(account.delegated_amount, 100);
  1558. // delegate insufficient funds
  1559. let instruction = transfer(
  1560. &program_id,
  1561. account_info.key,
  1562. account_info.key,
  1563. delegate_info.key,
  1564. &[],
  1565. 101,
  1566. )
  1567. .unwrap();
  1568. assert_eq!(
  1569. Err(TokenError::InsufficientFunds.into()),
  1570. do_process_instruction_dups(
  1571. instruction,
  1572. vec![
  1573. account_info.clone(),
  1574. account_info.clone(),
  1575. delegate_info.clone(),
  1576. ],
  1577. &[Check::err(TokenError::InsufficientFunds.into())],
  1578. )
  1579. );
  1580. // delegate insufficient funds checked
  1581. let instruction = transfer_checked(
  1582. &program_id,
  1583. account_info.key,
  1584. mint_info.key,
  1585. account_info.key,
  1586. delegate_info.key,
  1587. &[],
  1588. 101,
  1589. 2,
  1590. )
  1591. .unwrap();
  1592. assert_eq!(
  1593. Err(TokenError::InsufficientFunds.into()),
  1594. do_process_instruction_dups(
  1595. instruction,
  1596. vec![
  1597. account_info.clone(),
  1598. mint_info.clone(),
  1599. account_info.clone(),
  1600. delegate_info.clone(),
  1601. ],
  1602. &[Check::err(TokenError::InsufficientFunds.into())],
  1603. )
  1604. );
  1605. // owner transfer with delegate assigned
  1606. let instruction = transfer(
  1607. &program_id,
  1608. account_info.key,
  1609. account_info.key,
  1610. owner_info.key,
  1611. &[],
  1612. 1000,
  1613. )
  1614. .unwrap();
  1615. assert_eq!(
  1616. Ok(()),
  1617. do_process_instruction_dups(
  1618. instruction,
  1619. vec![
  1620. account_info.clone(),
  1621. account_info.clone(),
  1622. owner_info.clone(),
  1623. ],
  1624. &[
  1625. Check::success(),
  1626. Check::account(account_info.key)
  1627. .data_slice(64, &1000u64.to_le_bytes())
  1628. .build(),
  1629. ],
  1630. )
  1631. );
  1632. // no balance change...
  1633. let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
  1634. assert_eq!(account.amount, 1000);
  1635. // owner transfer with delegate assigned checked
  1636. let instruction = transfer_checked(
  1637. &program_id,
  1638. account_info.key,
  1639. mint_info.key,
  1640. account_info.key,
  1641. owner_info.key,
  1642. &[],
  1643. 1000,
  1644. 2,
  1645. )
  1646. .unwrap();
  1647. assert_eq!(
  1648. Ok(()),
  1649. do_process_instruction_dups(
  1650. instruction,
  1651. vec![
  1652. account_info.clone(),
  1653. mint_info.clone(),
  1654. account_info.clone(),
  1655. owner_info.clone(),
  1656. ],
  1657. &[
  1658. Check::success(),
  1659. Check::account(account_info.key)
  1660. .data_slice(64, &1000u64.to_le_bytes())
  1661. .build(),
  1662. ],
  1663. )
  1664. );
  1665. // no balance change...
  1666. let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
  1667. assert_eq!(account.amount, 1000);
  1668. }
  1669. #[test]
  1670. fn test_mintable_token_with_zero_supply() {
  1671. let program_id = spl_token::id();
  1672. let account_key = Pubkey::new_unique();
  1673. let mut account_account = SolanaAccount::new(
  1674. account_minimum_balance(),
  1675. Account::get_packed_len(),
  1676. &program_id,
  1677. );
  1678. let owner_key = Pubkey::new_unique();
  1679. let mut owner_account = SolanaAccount::default();
  1680. let mint_key = Pubkey::new_unique();
  1681. let mut mint_account =
  1682. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  1683. let mut rent_sysvar = rent_sysvar();
  1684. // create mint-able token with zero supply
  1685. let decimals = 2;
  1686. let expected_mint = Mint {
  1687. mint_authority: COption::Some(owner_key),
  1688. supply: 0,
  1689. decimals,
  1690. is_initialized: true,
  1691. freeze_authority: COption::None,
  1692. };
  1693. let mut mint_data = [0u8; Mint::LEN];
  1694. expected_mint.pack_into_slice(&mut mint_data);
  1695. do_process_instruction(
  1696. initialize_mint(&program_id, &mint_key, &owner_key, None, decimals).unwrap(),
  1697. vec![&mut mint_account, &mut rent_sysvar],
  1698. &[
  1699. Check::success(),
  1700. Check::account(&mint_key).data(&mint_data).build(),
  1701. ],
  1702. )
  1703. .unwrap();
  1704. let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
  1705. assert_eq!(mint, expected_mint);
  1706. // create account
  1707. do_process_instruction(
  1708. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  1709. vec![
  1710. &mut account_account,
  1711. &mut mint_account,
  1712. &mut owner_account,
  1713. &mut rent_sysvar,
  1714. ],
  1715. &[Check::success()],
  1716. )
  1717. .unwrap();
  1718. // mint to
  1719. do_process_instruction(
  1720. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
  1721. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1722. &[
  1723. Check::success(),
  1724. Check::account(&account_key)
  1725. .data_slice(64, &42u64.to_le_bytes())
  1726. .build(),
  1727. ],
  1728. )
  1729. .unwrap();
  1730. let _ = Mint::unpack(&mint_account.data).unwrap();
  1731. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  1732. assert_eq!(account.amount, 42);
  1733. // mint to 2, with incorrect decimals
  1734. assert_eq!(
  1735. Err(TokenError::MintDecimalsMismatch.into()),
  1736. do_process_instruction(
  1737. mint_to_checked(
  1738. &program_id,
  1739. &mint_key,
  1740. &account_key,
  1741. &owner_key,
  1742. &[],
  1743. 42,
  1744. decimals + 1
  1745. )
  1746. .unwrap(),
  1747. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1748. &[
  1749. Check::err(TokenError::MintDecimalsMismatch.into()),
  1750. Check::account(&account_key)
  1751. .data_slice(64, &42u64.to_le_bytes())
  1752. .build(),
  1753. ],
  1754. )
  1755. );
  1756. let _ = Mint::unpack(&mint_account.data).unwrap();
  1757. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  1758. assert_eq!(account.amount, 42);
  1759. // mint to 2
  1760. do_process_instruction(
  1761. mint_to_checked(
  1762. &program_id,
  1763. &mint_key,
  1764. &account_key,
  1765. &owner_key,
  1766. &[],
  1767. 42,
  1768. decimals,
  1769. )
  1770. .unwrap(),
  1771. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1772. &[
  1773. Check::success(),
  1774. Check::account(&account_key)
  1775. .data_slice(64, &84u64.to_le_bytes())
  1776. .build(),
  1777. ],
  1778. )
  1779. .unwrap();
  1780. let _ = Mint::unpack(&mint_account.data).unwrap();
  1781. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  1782. assert_eq!(account.amount, 84);
  1783. }
  1784. #[test]
  1785. fn test_approve_dups() {
  1786. let program_id = spl_token::id();
  1787. let account1_key = Pubkey::new_unique();
  1788. let mut account1_account = SolanaAccount::new(
  1789. account_minimum_balance(),
  1790. Account::get_packed_len(),
  1791. &program_id,
  1792. );
  1793. let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
  1794. let account2_key = Pubkey::new_unique();
  1795. let mut account2_account = SolanaAccount::new(
  1796. account_minimum_balance(),
  1797. Account::get_packed_len(),
  1798. &program_id,
  1799. );
  1800. let account2_info: AccountInfo = (&account2_key, false, &mut account2_account).into();
  1801. let account3_key = Pubkey::new_unique();
  1802. let mut account3_account = SolanaAccount::new(
  1803. account_minimum_balance(),
  1804. Account::get_packed_len(),
  1805. &program_id,
  1806. );
  1807. let account3_info: AccountInfo = (&account3_key, true, &mut account3_account).into();
  1808. let multisig_key = Pubkey::new_unique();
  1809. let mut multisig_account = SolanaAccount::new(
  1810. multisig_minimum_balance(),
  1811. Multisig::get_packed_len(),
  1812. &program_id,
  1813. );
  1814. let multisig_info: AccountInfo = (&multisig_key, true, &mut multisig_account).into();
  1815. let owner_key = Pubkey::new_unique();
  1816. let mut owner_account = SolanaAccount::default();
  1817. let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
  1818. let mint_key = Pubkey::new_unique();
  1819. let mut mint_account =
  1820. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  1821. let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
  1822. let rent_key = rent::id();
  1823. let mut rent_sysvar = rent_sysvar();
  1824. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  1825. // create mint
  1826. do_process_instruction_dups(
  1827. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  1828. vec![mint_info.clone(), rent_info.clone()],
  1829. &[Check::success()],
  1830. )
  1831. .unwrap();
  1832. // create account
  1833. do_process_instruction_dups(
  1834. initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
  1835. vec![
  1836. account1_info.clone(),
  1837. mint_info.clone(),
  1838. account1_info.clone(),
  1839. rent_info.clone(),
  1840. ],
  1841. &[Check::success()],
  1842. )
  1843. .unwrap();
  1844. // create another account
  1845. do_process_instruction_dups(
  1846. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  1847. vec![
  1848. account2_info.clone(),
  1849. mint_info.clone(),
  1850. owner_info.clone(),
  1851. rent_info.clone(),
  1852. ],
  1853. &[Check::success()],
  1854. )
  1855. .unwrap();
  1856. // mint to account
  1857. do_process_instruction_dups(
  1858. mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
  1859. vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
  1860. &[Check::success()],
  1861. )
  1862. .unwrap();
  1863. // source-owner approve
  1864. do_process_instruction_dups(
  1865. approve(
  1866. &program_id,
  1867. &account1_key,
  1868. &account2_key,
  1869. &account1_key,
  1870. &[],
  1871. 500,
  1872. )
  1873. .unwrap(),
  1874. vec![
  1875. account1_info.clone(),
  1876. account2_info.clone(),
  1877. account1_info.clone(),
  1878. ],
  1879. &[Check::success()],
  1880. )
  1881. .unwrap();
  1882. // source-owner approve_checked
  1883. do_process_instruction_dups(
  1884. approve_checked(
  1885. &program_id,
  1886. &account1_key,
  1887. &mint_key,
  1888. &account2_key,
  1889. &account1_key,
  1890. &[],
  1891. 500,
  1892. 2,
  1893. )
  1894. .unwrap(),
  1895. vec![
  1896. account1_info.clone(),
  1897. mint_info.clone(),
  1898. account2_info.clone(),
  1899. account1_info.clone(),
  1900. ],
  1901. &[Check::success()],
  1902. )
  1903. .unwrap();
  1904. // source-owner revoke
  1905. do_process_instruction_dups(
  1906. revoke(&program_id, &account1_key, &account1_key, &[]).unwrap(),
  1907. vec![account1_info.clone(), account1_info.clone()],
  1908. &[Check::success()],
  1909. )
  1910. .unwrap();
  1911. // test source-multisig signer
  1912. do_process_instruction_dups(
  1913. initialize_multisig(&program_id, &multisig_key, &[&account3_key], 1).unwrap(),
  1914. vec![
  1915. multisig_info.clone(),
  1916. rent_info.clone(),
  1917. account3_info.clone(),
  1918. ],
  1919. &[Check::success()],
  1920. )
  1921. .unwrap();
  1922. do_process_instruction_dups(
  1923. initialize_account(&program_id, &account3_key, &mint_key, &multisig_key).unwrap(),
  1924. vec![
  1925. account3_info.clone(),
  1926. mint_info.clone(),
  1927. multisig_info.clone(),
  1928. rent_info.clone(),
  1929. ],
  1930. &[Check::success()],
  1931. )
  1932. .unwrap();
  1933. do_process_instruction_dups(
  1934. mint_to(&program_id, &mint_key, &account3_key, &owner_key, &[], 1000).unwrap(),
  1935. vec![mint_info.clone(), account3_info.clone(), owner_info.clone()],
  1936. &[Check::success()],
  1937. )
  1938. .unwrap();
  1939. // source-multisig-signer approve
  1940. do_process_instruction_dups(
  1941. approve(
  1942. &program_id,
  1943. &account3_key,
  1944. &account2_key,
  1945. &multisig_key,
  1946. &[&account3_key],
  1947. 500,
  1948. )
  1949. .unwrap(),
  1950. vec![
  1951. account3_info.clone(),
  1952. account2_info.clone(),
  1953. multisig_info.clone(),
  1954. account3_info.clone(),
  1955. ],
  1956. &[Check::success()],
  1957. )
  1958. .unwrap();
  1959. // source-multisig-signer approve_checked
  1960. do_process_instruction_dups(
  1961. approve_checked(
  1962. &program_id,
  1963. &account3_key,
  1964. &mint_key,
  1965. &account2_key,
  1966. &multisig_key,
  1967. &[&account3_key],
  1968. 500,
  1969. 2,
  1970. )
  1971. .unwrap(),
  1972. vec![
  1973. account3_info.clone(),
  1974. mint_info.clone(),
  1975. account2_info.clone(),
  1976. multisig_info.clone(),
  1977. account3_info.clone(),
  1978. ],
  1979. &[Check::success()],
  1980. )
  1981. .unwrap();
  1982. // source-owner multisig-signer
  1983. do_process_instruction_dups(
  1984. revoke(&program_id, &account3_key, &multisig_key, &[&account3_key]).unwrap(),
  1985. vec![
  1986. account3_info.clone(),
  1987. multisig_info.clone(),
  1988. account3_info.clone(),
  1989. ],
  1990. &[Check::success()],
  1991. )
  1992. .unwrap();
  1993. }
  1994. #[test]
  1995. fn test_approve() {
  1996. let program_id = spl_token::id();
  1997. let account_key = Pubkey::new_unique();
  1998. let mut account_account = SolanaAccount::new(
  1999. account_minimum_balance(),
  2000. Account::get_packed_len(),
  2001. &program_id,
  2002. );
  2003. let account2_key = Pubkey::new_unique();
  2004. let mut account2_account = SolanaAccount::new(
  2005. account_minimum_balance(),
  2006. Account::get_packed_len(),
  2007. &program_id,
  2008. );
  2009. let delegate_key = Pubkey::new_unique();
  2010. let mut delegate_account = SolanaAccount::default();
  2011. let owner_key = Pubkey::new_unique();
  2012. let mut owner_account = SolanaAccount::default();
  2013. let owner2_key = Pubkey::new_unique();
  2014. let mut owner2_account = SolanaAccount::default();
  2015. let mint_key = Pubkey::new_unique();
  2016. let mut mint_account =
  2017. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  2018. let mut rent_sysvar = rent_sysvar();
  2019. // create mint
  2020. do_process_instruction(
  2021. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  2022. vec![&mut mint_account, &mut rent_sysvar],
  2023. &[Check::success()],
  2024. )
  2025. .unwrap();
  2026. // create account
  2027. do_process_instruction(
  2028. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  2029. vec![
  2030. &mut account_account,
  2031. &mut mint_account,
  2032. &mut owner_account,
  2033. &mut rent_sysvar,
  2034. ],
  2035. &[Check::success()],
  2036. )
  2037. .unwrap();
  2038. // create another account
  2039. do_process_instruction(
  2040. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  2041. vec![
  2042. &mut account2_account,
  2043. &mut mint_account,
  2044. &mut owner_account,
  2045. &mut rent_sysvar,
  2046. ],
  2047. &[Check::success()],
  2048. )
  2049. .unwrap();
  2050. // mint to account
  2051. do_process_instruction(
  2052. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  2053. vec![&mut mint_account, &mut account_account, &mut owner_account],
  2054. &[Check::success()],
  2055. )
  2056. .unwrap();
  2057. // missing signer
  2058. let mut instruction = approve(
  2059. &program_id,
  2060. &account_key,
  2061. &delegate_key,
  2062. &owner_key,
  2063. &[],
  2064. 100,
  2065. )
  2066. .unwrap();
  2067. instruction.accounts[2].is_signer = false;
  2068. assert_eq!(
  2069. Err(ProgramError::MissingRequiredSignature),
  2070. do_process_instruction(
  2071. instruction,
  2072. vec![
  2073. &mut account_account,
  2074. &mut delegate_account,
  2075. &mut owner_account,
  2076. ],
  2077. &[Check::err(ProgramError::MissingRequiredSignature)],
  2078. )
  2079. );
  2080. // no owner
  2081. assert_eq!(
  2082. Err(TokenError::OwnerMismatch.into()),
  2083. do_process_instruction(
  2084. approve(
  2085. &program_id,
  2086. &account_key,
  2087. &delegate_key,
  2088. &owner2_key,
  2089. &[],
  2090. 100
  2091. )
  2092. .unwrap(),
  2093. vec![
  2094. &mut account_account,
  2095. &mut delegate_account,
  2096. &mut owner2_account,
  2097. ],
  2098. &[Check::err(TokenError::OwnerMismatch.into())],
  2099. )
  2100. );
  2101. // approve delegate
  2102. do_process_instruction(
  2103. approve(
  2104. &program_id,
  2105. &account_key,
  2106. &delegate_key,
  2107. &owner_key,
  2108. &[],
  2109. 100,
  2110. )
  2111. .unwrap(),
  2112. vec![
  2113. &mut account_account,
  2114. &mut delegate_account,
  2115. &mut owner_account,
  2116. ],
  2117. &[Check::success()],
  2118. )
  2119. .unwrap();
  2120. // approve delegate 2, with incorrect decimals
  2121. assert_eq!(
  2122. Err(TokenError::MintDecimalsMismatch.into()),
  2123. do_process_instruction(
  2124. approve_checked(
  2125. &program_id,
  2126. &account_key,
  2127. &mint_key,
  2128. &delegate_key,
  2129. &owner_key,
  2130. &[],
  2131. 100,
  2132. 0 // <-- incorrect decimals
  2133. )
  2134. .unwrap(),
  2135. vec![
  2136. &mut account_account,
  2137. &mut mint_account,
  2138. &mut delegate_account,
  2139. &mut owner_account,
  2140. ],
  2141. &[Check::err(TokenError::MintDecimalsMismatch.into())],
  2142. )
  2143. );
  2144. // approve delegate 2, with incorrect mint
  2145. assert_eq!(
  2146. Err(TokenError::MintMismatch.into()),
  2147. do_process_instruction(
  2148. approve_checked(
  2149. &program_id,
  2150. &account_key,
  2151. &account2_key, // <-- bad mint
  2152. &delegate_key,
  2153. &owner_key,
  2154. &[],
  2155. 100,
  2156. 0
  2157. )
  2158. .unwrap(),
  2159. vec![
  2160. &mut account_account,
  2161. &mut account2_account, // <-- bad mint
  2162. &mut delegate_account,
  2163. &mut owner_account,
  2164. ],
  2165. &[Check::err(TokenError::MintMismatch.into())],
  2166. )
  2167. );
  2168. // approve delegate 2
  2169. do_process_instruction(
  2170. approve_checked(
  2171. &program_id,
  2172. &account_key,
  2173. &mint_key,
  2174. &delegate_key,
  2175. &owner_key,
  2176. &[],
  2177. 100,
  2178. 2,
  2179. )
  2180. .unwrap(),
  2181. vec![
  2182. &mut account_account,
  2183. &mut mint_account,
  2184. &mut delegate_account,
  2185. &mut owner_account,
  2186. ],
  2187. &[Check::success()],
  2188. )
  2189. .unwrap();
  2190. // revoke delegate
  2191. do_process_instruction(
  2192. revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
  2193. vec![&mut account_account, &mut owner_account],
  2194. &[Check::success()],
  2195. )
  2196. .unwrap();
  2197. }
  2198. #[test]
  2199. fn test_set_authority_dups() {
  2200. let program_id = spl_token::id();
  2201. let account1_key = Pubkey::new_unique();
  2202. let mut account1_account = SolanaAccount::new(
  2203. account_minimum_balance(),
  2204. Account::get_packed_len(),
  2205. &program_id,
  2206. );
  2207. let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
  2208. let owner_key = Pubkey::new_unique();
  2209. let mint_key = Pubkey::new_unique();
  2210. let mut mint_account =
  2211. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  2212. let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
  2213. let rent_key = rent::id();
  2214. let mut rent_sysvar = rent_sysvar();
  2215. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  2216. // create mint
  2217. do_process_instruction_dups(
  2218. initialize_mint(&program_id, &mint_key, &mint_key, Some(&mint_key), 2).unwrap(),
  2219. vec![mint_info.clone(), rent_info.clone()],
  2220. &[Check::success()],
  2221. )
  2222. .unwrap();
  2223. // create account
  2224. do_process_instruction_dups(
  2225. initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
  2226. vec![
  2227. account1_info.clone(),
  2228. mint_info.clone(),
  2229. account1_info.clone(),
  2230. rent_info.clone(),
  2231. ],
  2232. &[Check::success()],
  2233. )
  2234. .unwrap();
  2235. // set mint_authority when currently self
  2236. do_process_instruction_dups(
  2237. set_authority(
  2238. &program_id,
  2239. &mint_key,
  2240. Some(&owner_key),
  2241. AuthorityType::MintTokens,
  2242. &mint_key,
  2243. &[],
  2244. )
  2245. .unwrap(),
  2246. vec![mint_info.clone(), mint_info.clone()],
  2247. &[Check::success()],
  2248. )
  2249. .unwrap();
  2250. // set freeze_authority when currently self
  2251. do_process_instruction_dups(
  2252. set_authority(
  2253. &program_id,
  2254. &mint_key,
  2255. Some(&owner_key),
  2256. AuthorityType::FreezeAccount,
  2257. &mint_key,
  2258. &[],
  2259. )
  2260. .unwrap(),
  2261. vec![mint_info.clone(), mint_info.clone()],
  2262. &[Check::success()],
  2263. )
  2264. .unwrap();
  2265. // set account owner when currently self
  2266. do_process_instruction_dups(
  2267. set_authority(
  2268. &program_id,
  2269. &account1_key,
  2270. Some(&owner_key),
  2271. AuthorityType::AccountOwner,
  2272. &account1_key,
  2273. &[],
  2274. )
  2275. .unwrap(),
  2276. vec![account1_info.clone(), account1_info.clone()],
  2277. &[Check::success()],
  2278. )
  2279. .unwrap();
  2280. // set close_authority when currently self
  2281. let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
  2282. account.close_authority = COption::Some(account1_key);
  2283. Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
  2284. do_process_instruction_dups(
  2285. set_authority(
  2286. &program_id,
  2287. &account1_key,
  2288. Some(&owner_key),
  2289. AuthorityType::CloseAccount,
  2290. &account1_key,
  2291. &[],
  2292. )
  2293. .unwrap(),
  2294. vec![account1_info.clone(), account1_info.clone()],
  2295. &[Check::success()],
  2296. )
  2297. .unwrap();
  2298. }
  2299. #[test]
  2300. fn test_set_authority() {
  2301. let program_id = spl_token::id();
  2302. let account_key = Pubkey::new_unique();
  2303. let mut account_account = SolanaAccount::new(
  2304. account_minimum_balance(),
  2305. Account::get_packed_len(),
  2306. &program_id,
  2307. );
  2308. let account2_key = Pubkey::new_unique();
  2309. let mut account2_account = SolanaAccount::new(
  2310. account_minimum_balance(),
  2311. Account::get_packed_len(),
  2312. &program_id,
  2313. );
  2314. let owner_key = Pubkey::new_unique();
  2315. let mut owner_account = SolanaAccount::default();
  2316. let owner2_key = Pubkey::new_unique();
  2317. let mut owner2_account = SolanaAccount::default();
  2318. let owner3_key = Pubkey::new_unique();
  2319. let mut owner3_account = SolanaAccount::default();
  2320. let mint_key = Pubkey::new_unique();
  2321. let mut mint_account =
  2322. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  2323. let mint2_key = Pubkey::new_unique();
  2324. let mut mint2_account =
  2325. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  2326. let mut rent_sysvar = rent_sysvar();
  2327. // create new mint with owner
  2328. do_process_instruction(
  2329. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  2330. vec![&mut mint_account, &mut rent_sysvar],
  2331. &[Check::success()],
  2332. )
  2333. .unwrap();
  2334. // create mint with owner and freeze_authority
  2335. do_process_instruction(
  2336. initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
  2337. vec![&mut mint2_account, &mut rent_sysvar],
  2338. &[Check::success()],
  2339. )
  2340. .unwrap();
  2341. // invalid account
  2342. assert_eq!(
  2343. Err(ProgramError::UninitializedAccount),
  2344. do_process_instruction(
  2345. set_authority(
  2346. &program_id,
  2347. &account_key,
  2348. Some(&owner2_key),
  2349. AuthorityType::AccountOwner,
  2350. &owner_key,
  2351. &[]
  2352. )
  2353. .unwrap(),
  2354. vec![&mut account_account, &mut owner_account],
  2355. &[Check::err(ProgramError::UninitializedAccount)],
  2356. )
  2357. );
  2358. // create account
  2359. do_process_instruction(
  2360. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  2361. vec![
  2362. &mut account_account,
  2363. &mut mint_account,
  2364. &mut owner_account,
  2365. &mut rent_sysvar,
  2366. ],
  2367. &[Check::success()],
  2368. )
  2369. .unwrap();
  2370. // create another account
  2371. do_process_instruction(
  2372. initialize_account(&program_id, &account2_key, &mint2_key, &owner_key).unwrap(),
  2373. vec![
  2374. &mut account2_account,
  2375. &mut mint2_account,
  2376. &mut owner_account,
  2377. &mut rent_sysvar,
  2378. ],
  2379. &[Check::success()],
  2380. )
  2381. .unwrap();
  2382. // missing owner
  2383. assert_eq!(
  2384. Err(TokenError::OwnerMismatch.into()),
  2385. do_process_instruction(
  2386. set_authority(
  2387. &program_id,
  2388. &account_key,
  2389. Some(&owner_key),
  2390. AuthorityType::AccountOwner,
  2391. &owner2_key,
  2392. &[]
  2393. )
  2394. .unwrap(),
  2395. vec![&mut account_account, &mut owner2_account],
  2396. &[Check::err(TokenError::OwnerMismatch.into())],
  2397. )
  2398. );
  2399. // owner did not sign
  2400. let mut instruction = set_authority(
  2401. &program_id,
  2402. &account_key,
  2403. Some(&owner2_key),
  2404. AuthorityType::AccountOwner,
  2405. &owner_key,
  2406. &[],
  2407. )
  2408. .unwrap();
  2409. instruction.accounts[1].is_signer = false;
  2410. assert_eq!(
  2411. Err(ProgramError::MissingRequiredSignature),
  2412. do_process_instruction(
  2413. instruction,
  2414. vec![&mut account_account, &mut owner_account,],
  2415. &[Check::err(ProgramError::MissingRequiredSignature)]
  2416. ),
  2417. );
  2418. // wrong authority type
  2419. assert_eq!(
  2420. Err(TokenError::AuthorityTypeNotSupported.into()),
  2421. do_process_instruction(
  2422. set_authority(
  2423. &program_id,
  2424. &account_key,
  2425. Some(&owner2_key),
  2426. AuthorityType::FreezeAccount,
  2427. &owner_key,
  2428. &[],
  2429. )
  2430. .unwrap(),
  2431. vec![&mut account_account, &mut owner_account],
  2432. &[Check::err(TokenError::AuthorityTypeNotSupported.into())],
  2433. )
  2434. );
  2435. // account owner may not be set to None
  2436. assert_eq!(
  2437. Err(TokenError::InvalidInstruction.into()),
  2438. do_process_instruction(
  2439. set_authority(
  2440. &program_id,
  2441. &account_key,
  2442. None,
  2443. AuthorityType::AccountOwner,
  2444. &owner_key,
  2445. &[],
  2446. )
  2447. .unwrap(),
  2448. vec![&mut account_account, &mut owner_account],
  2449. &[Check::err(TokenError::InvalidInstruction.into())],
  2450. )
  2451. );
  2452. // set delegate
  2453. do_process_instruction(
  2454. approve(
  2455. &program_id,
  2456. &account_key,
  2457. &owner2_key,
  2458. &owner_key,
  2459. &[],
  2460. u64::MAX,
  2461. )
  2462. .unwrap(),
  2463. vec![
  2464. &mut account_account,
  2465. &mut owner2_account,
  2466. &mut owner_account,
  2467. ],
  2468. &[
  2469. Check::success(),
  2470. // delegate set
  2471. Check::account(&account_key)
  2472. .data_slice(72, &[1, 0, 0, 0])
  2473. .build(),
  2474. // delegate
  2475. Check::account(&account_key)
  2476. .data_slice(76, owner2_key.as_ref())
  2477. .build(),
  2478. // delegated amount
  2479. Check::account(&account_key)
  2480. .data_slice(121, &u64::MAX.to_le_bytes())
  2481. .build(),
  2482. ],
  2483. )
  2484. .unwrap();
  2485. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  2486. assert_eq!(account.delegate, COption::Some(owner2_key));
  2487. assert_eq!(account.delegated_amount, u64::MAX);
  2488. // set owner
  2489. do_process_instruction(
  2490. set_authority(
  2491. &program_id,
  2492. &account_key,
  2493. Some(&owner3_key),
  2494. AuthorityType::AccountOwner,
  2495. &owner_key,
  2496. &[],
  2497. )
  2498. .unwrap(),
  2499. vec![&mut account_account, &mut owner_account],
  2500. &[
  2501. Check::success(),
  2502. // delegate not set
  2503. Check::account(&account_key)
  2504. .data_slice(72, &[0, 0, 0, 0])
  2505. .build(),
  2506. // delegated amount
  2507. Check::account(&account_key)
  2508. .data_slice(121, &0u64.to_le_bytes())
  2509. .build(),
  2510. ],
  2511. )
  2512. .unwrap();
  2513. // check delegate cleared
  2514. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  2515. assert_eq!(account.delegate, COption::None);
  2516. assert_eq!(account.delegated_amount, 0);
  2517. // set owner without existing delegate
  2518. do_process_instruction(
  2519. set_authority(
  2520. &program_id,
  2521. &account_key,
  2522. Some(&owner2_key),
  2523. AuthorityType::AccountOwner,
  2524. &owner3_key,
  2525. &[],
  2526. )
  2527. .unwrap(),
  2528. vec![&mut account_account, &mut owner3_account],
  2529. &[Check::success()],
  2530. )
  2531. .unwrap();
  2532. // set close_authority
  2533. do_process_instruction(
  2534. set_authority(
  2535. &program_id,
  2536. &account_key,
  2537. Some(&owner2_key),
  2538. AuthorityType::CloseAccount,
  2539. &owner2_key,
  2540. &[],
  2541. )
  2542. .unwrap(),
  2543. vec![&mut account_account, &mut owner2_account],
  2544. &[Check::success()],
  2545. )
  2546. .unwrap();
  2547. // close_authority may be set to None
  2548. do_process_instruction(
  2549. set_authority(
  2550. &program_id,
  2551. &account_key,
  2552. None,
  2553. AuthorityType::CloseAccount,
  2554. &owner2_key,
  2555. &[],
  2556. )
  2557. .unwrap(),
  2558. vec![&mut account_account, &mut owner2_account],
  2559. &[Check::success()],
  2560. )
  2561. .unwrap();
  2562. // wrong owner
  2563. assert_eq!(
  2564. Err(TokenError::OwnerMismatch.into()),
  2565. do_process_instruction(
  2566. set_authority(
  2567. &program_id,
  2568. &mint_key,
  2569. Some(&owner3_key),
  2570. AuthorityType::MintTokens,
  2571. &owner2_key,
  2572. &[]
  2573. )
  2574. .unwrap(),
  2575. vec![&mut mint_account, &mut owner2_account],
  2576. &[Check::err(TokenError::OwnerMismatch.into())],
  2577. )
  2578. );
  2579. // owner did not sign
  2580. let mut instruction = set_authority(
  2581. &program_id,
  2582. &mint_key,
  2583. Some(&owner2_key),
  2584. AuthorityType::MintTokens,
  2585. &owner_key,
  2586. &[],
  2587. )
  2588. .unwrap();
  2589. instruction.accounts[1].is_signer = false;
  2590. assert_eq!(
  2591. Err(ProgramError::MissingRequiredSignature),
  2592. do_process_instruction(
  2593. instruction,
  2594. vec![&mut mint_account, &mut owner_account],
  2595. &[Check::err(ProgramError::MissingRequiredSignature)]
  2596. ),
  2597. );
  2598. // cannot freeze
  2599. assert_eq!(
  2600. Err(TokenError::MintCannotFreeze.into()),
  2601. do_process_instruction(
  2602. set_authority(
  2603. &program_id,
  2604. &mint_key,
  2605. Some(&owner2_key),
  2606. AuthorityType::FreezeAccount,
  2607. &owner_key,
  2608. &[],
  2609. )
  2610. .unwrap(),
  2611. vec![&mut mint_account, &mut owner_account],
  2612. &[Check::err(TokenError::MintCannotFreeze.into())],
  2613. )
  2614. );
  2615. // set owner
  2616. do_process_instruction(
  2617. set_authority(
  2618. &program_id,
  2619. &mint_key,
  2620. Some(&owner2_key),
  2621. AuthorityType::MintTokens,
  2622. &owner_key,
  2623. &[],
  2624. )
  2625. .unwrap(),
  2626. vec![&mut mint_account, &mut owner_account],
  2627. &[Check::success()],
  2628. )
  2629. .unwrap();
  2630. // set owner to None
  2631. do_process_instruction(
  2632. set_authority(
  2633. &program_id,
  2634. &mint_key,
  2635. None,
  2636. AuthorityType::MintTokens,
  2637. &owner2_key,
  2638. &[],
  2639. )
  2640. .unwrap(),
  2641. vec![&mut mint_account, &mut owner2_account],
  2642. &[Check::success()],
  2643. )
  2644. .unwrap();
  2645. // test unsetting mint_authority is one-way operation
  2646. assert_eq!(
  2647. Err(TokenError::FixedSupply.into()),
  2648. do_process_instruction(
  2649. set_authority(
  2650. &program_id,
  2651. &mint2_key,
  2652. Some(&owner2_key),
  2653. AuthorityType::MintTokens,
  2654. &owner_key,
  2655. &[]
  2656. )
  2657. .unwrap(),
  2658. vec![&mut mint_account, &mut owner_account],
  2659. &[Check::err(TokenError::FixedSupply.into())],
  2660. )
  2661. );
  2662. // set freeze_authority
  2663. do_process_instruction(
  2664. set_authority(
  2665. &program_id,
  2666. &mint2_key,
  2667. Some(&owner2_key),
  2668. AuthorityType::FreezeAccount,
  2669. &owner_key,
  2670. &[],
  2671. )
  2672. .unwrap(),
  2673. vec![&mut mint2_account, &mut owner_account],
  2674. &[Check::success()],
  2675. )
  2676. .unwrap();
  2677. // test unsetting freeze_authority is one-way operation
  2678. do_process_instruction(
  2679. set_authority(
  2680. &program_id,
  2681. &mint2_key,
  2682. None,
  2683. AuthorityType::FreezeAccount,
  2684. &owner2_key,
  2685. &[],
  2686. )
  2687. .unwrap(),
  2688. vec![&mut mint2_account, &mut owner2_account],
  2689. &[Check::success()],
  2690. )
  2691. .unwrap();
  2692. assert_eq!(
  2693. Err(TokenError::MintCannotFreeze.into()),
  2694. do_process_instruction(
  2695. set_authority(
  2696. &program_id,
  2697. &mint2_key,
  2698. Some(&owner2_key),
  2699. AuthorityType::FreezeAccount,
  2700. &owner_key,
  2701. &[],
  2702. )
  2703. .unwrap(),
  2704. vec![&mut mint2_account, &mut owner2_account],
  2705. &[Check::err(TokenError::MintCannotFreeze.into())],
  2706. )
  2707. );
  2708. }
  2709. #[test]
  2710. fn test_mint_to_dups() {
  2711. let program_id = spl_token::id();
  2712. let account1_key = Pubkey::new_unique();
  2713. let mut account1_account = SolanaAccount::new(
  2714. account_minimum_balance(),
  2715. Account::get_packed_len(),
  2716. &program_id,
  2717. );
  2718. let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
  2719. let owner_key = Pubkey::new_unique();
  2720. let mut owner_account = SolanaAccount::default();
  2721. let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
  2722. let mint_key = Pubkey::new_unique();
  2723. let mut mint_account =
  2724. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  2725. let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
  2726. let rent_key = rent::id();
  2727. let mut rent_sysvar = rent_sysvar();
  2728. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  2729. // create mint
  2730. do_process_instruction_dups(
  2731. initialize_mint(&program_id, &mint_key, &mint_key, None, 2).unwrap(),
  2732. vec![mint_info.clone(), rent_info.clone()],
  2733. &[Check::success()],
  2734. )
  2735. .unwrap();
  2736. // create account
  2737. do_process_instruction_dups(
  2738. initialize_account(&program_id, &account1_key, &mint_key, &owner_key).unwrap(),
  2739. vec![
  2740. account1_info.clone(),
  2741. mint_info.clone(),
  2742. owner_info.clone(),
  2743. rent_info.clone(),
  2744. ],
  2745. &[Check::success()],
  2746. )
  2747. .unwrap();
  2748. // mint_to when mint_authority is self
  2749. do_process_instruction_dups(
  2750. mint_to(&program_id, &mint_key, &account1_key, &mint_key, &[], 42).unwrap(),
  2751. vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
  2752. &[Check::success()],
  2753. )
  2754. .unwrap();
  2755. // mint_to_checked when mint_authority is self
  2756. do_process_instruction_dups(
  2757. mint_to_checked(&program_id, &mint_key, &account1_key, &mint_key, &[], 42, 2).unwrap(),
  2758. vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
  2759. &[Check::success()],
  2760. )
  2761. .unwrap();
  2762. // mint_to when mint_authority is account owner
  2763. let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow()).unwrap();
  2764. mint.mint_authority = COption::Some(account1_key);
  2765. Mint::pack(mint, &mut mint_info.data.borrow_mut()).unwrap();
  2766. do_process_instruction_dups(
  2767. mint_to(
  2768. &program_id,
  2769. &mint_key,
  2770. &account1_key,
  2771. &account1_key,
  2772. &[],
  2773. 42,
  2774. )
  2775. .unwrap(),
  2776. vec![
  2777. mint_info.clone(),
  2778. account1_info.clone(),
  2779. account1_info.clone(),
  2780. ],
  2781. &[Check::success()],
  2782. )
  2783. .unwrap();
  2784. // mint_to_checked when mint_authority is account owner
  2785. do_process_instruction_dups(
  2786. mint_to(
  2787. &program_id,
  2788. &mint_key,
  2789. &account1_key,
  2790. &account1_key,
  2791. &[],
  2792. 42,
  2793. )
  2794. .unwrap(),
  2795. vec![
  2796. mint_info.clone(),
  2797. account1_info.clone(),
  2798. account1_info.clone(),
  2799. ],
  2800. &[Check::success()],
  2801. )
  2802. .unwrap();
  2803. }
  2804. #[test]
  2805. fn test_mint_to() {
  2806. let program_id = spl_token::id();
  2807. let account_key = Pubkey::new_unique();
  2808. let mut account_account = SolanaAccount::new(
  2809. account_minimum_balance(),
  2810. Account::get_packed_len(),
  2811. &program_id,
  2812. );
  2813. let account2_key = Pubkey::new_unique();
  2814. let mut account2_account = SolanaAccount::new(
  2815. account_minimum_balance(),
  2816. Account::get_packed_len(),
  2817. &program_id,
  2818. );
  2819. let account3_key = Pubkey::new_unique();
  2820. let mut account3_account = SolanaAccount::new(
  2821. account_minimum_balance(),
  2822. Account::get_packed_len(),
  2823. &program_id,
  2824. );
  2825. let mismatch_key = Pubkey::new_unique();
  2826. let mut mismatch_account = SolanaAccount::new(
  2827. account_minimum_balance(),
  2828. Account::get_packed_len(),
  2829. &program_id,
  2830. );
  2831. let owner_key = Pubkey::new_unique();
  2832. let mut owner_account = SolanaAccount::default();
  2833. let owner2_key = Pubkey::new_unique();
  2834. let mut owner2_account = SolanaAccount::default();
  2835. let mint_key = Pubkey::new_unique();
  2836. let mut mint_account =
  2837. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  2838. let mint2_key = Pubkey::new_unique();
  2839. let uninitialized_key = Pubkey::new_unique();
  2840. let mut uninitialized_account = SolanaAccount::new(
  2841. account_minimum_balance(),
  2842. Account::get_packed_len(),
  2843. &program_id,
  2844. );
  2845. let mut rent_sysvar = rent_sysvar();
  2846. // create new mint with owner
  2847. do_process_instruction(
  2848. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  2849. vec![&mut mint_account, &mut rent_sysvar],
  2850. &[Check::success()],
  2851. )
  2852. .unwrap();
  2853. // create account
  2854. do_process_instruction(
  2855. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  2856. vec![
  2857. &mut account_account,
  2858. &mut mint_account,
  2859. &mut owner_account,
  2860. &mut rent_sysvar,
  2861. ],
  2862. &[Check::success()],
  2863. )
  2864. .unwrap();
  2865. // create another account
  2866. do_process_instruction(
  2867. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  2868. vec![
  2869. &mut account2_account,
  2870. &mut mint_account,
  2871. &mut owner_account,
  2872. &mut rent_sysvar,
  2873. ],
  2874. &[Check::success()],
  2875. )
  2876. .unwrap();
  2877. // create another account
  2878. do_process_instruction(
  2879. initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
  2880. vec![
  2881. &mut account3_account,
  2882. &mut mint_account,
  2883. &mut owner_account,
  2884. &mut rent_sysvar,
  2885. ],
  2886. &[Check::success()],
  2887. )
  2888. .unwrap();
  2889. // create mismatch account
  2890. do_process_instruction(
  2891. initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
  2892. vec![
  2893. &mut mismatch_account,
  2894. &mut mint_account,
  2895. &mut owner_account,
  2896. &mut rent_sysvar,
  2897. ],
  2898. &[Check::success()],
  2899. )
  2900. .unwrap();
  2901. let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
  2902. account.mint = mint2_key;
  2903. Account::pack(account, &mut mismatch_account.data).unwrap();
  2904. // mint to
  2905. do_process_instruction(
  2906. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
  2907. vec![&mut mint_account, &mut account_account, &mut owner_account],
  2908. &[
  2909. Check::success(),
  2910. Check::account(&mint_key)
  2911. .data_slice(36, &42u64.to_le_bytes())
  2912. .build(),
  2913. Check::account(&account_key)
  2914. .data_slice(64, &42u64.to_le_bytes())
  2915. .build(),
  2916. ],
  2917. )
  2918. .unwrap();
  2919. let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
  2920. assert_eq!(mint.supply, 42);
  2921. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  2922. assert_eq!(account.amount, 42);
  2923. // mint to another account to test supply accumulation
  2924. do_process_instruction(
  2925. mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
  2926. vec![&mut mint_account, &mut account2_account, &mut owner_account],
  2927. &[
  2928. Check::success(),
  2929. Check::account(&mint_key)
  2930. .data_slice(36, &84u64.to_le_bytes())
  2931. .build(),
  2932. Check::account(&account2_key)
  2933. .data_slice(64, &42u64.to_le_bytes())
  2934. .build(),
  2935. ],
  2936. )
  2937. .unwrap();
  2938. let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
  2939. assert_eq!(mint.supply, 84);
  2940. let account = Account::unpack_unchecked(&account2_account.data).unwrap();
  2941. assert_eq!(account.amount, 42);
  2942. // missing signer
  2943. let mut instruction =
  2944. mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap();
  2945. instruction.accounts[2].is_signer = false;
  2946. assert_eq!(
  2947. Err(ProgramError::MissingRequiredSignature),
  2948. do_process_instruction(
  2949. instruction,
  2950. vec![&mut mint_account, &mut account2_account, &mut owner_account],
  2951. &[Check::err(ProgramError::MissingRequiredSignature)],
  2952. )
  2953. );
  2954. // mismatch account
  2955. assert_eq!(
  2956. Err(TokenError::MintMismatch.into()),
  2957. do_process_instruction(
  2958. mint_to(&program_id, &mint_key, &mismatch_key, &owner_key, &[], 42).unwrap(),
  2959. vec![&mut mint_account, &mut mismatch_account, &mut owner_account],
  2960. &[Check::err(TokenError::MintMismatch.into())],
  2961. )
  2962. );
  2963. // missing owner
  2964. assert_eq!(
  2965. Err(TokenError::OwnerMismatch.into()),
  2966. do_process_instruction(
  2967. mint_to(&program_id, &mint_key, &account2_key, &owner2_key, &[], 42).unwrap(),
  2968. vec![
  2969. &mut mint_account,
  2970. &mut account2_account,
  2971. &mut owner2_account,
  2972. ],
  2973. &[Check::err(TokenError::OwnerMismatch.into())],
  2974. )
  2975. );
  2976. // mint not owned by program
  2977. let not_program_id = Pubkey::new_unique();
  2978. mint_account.owner = not_program_id;
  2979. assert_eq!(
  2980. Err(ProgramError::IncorrectProgramId),
  2981. do_process_instruction(
  2982. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 0).unwrap(),
  2983. vec![&mut mint_account, &mut account_account, &mut owner_account],
  2984. &[Check::err(ProgramError::IncorrectProgramId)],
  2985. )
  2986. );
  2987. mint_account.owner = program_id;
  2988. // account not owned by program
  2989. let not_program_id = Pubkey::new_unique();
  2990. account_account.owner = not_program_id;
  2991. assert_eq!(
  2992. Err(ProgramError::IncorrectProgramId),
  2993. do_process_instruction(
  2994. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 0).unwrap(),
  2995. vec![&mut mint_account, &mut account_account, &mut owner_account],
  2996. &[Check::err(ProgramError::IncorrectProgramId)],
  2997. )
  2998. );
  2999. account_account.owner = program_id;
  3000. // uninitialized destination account
  3001. assert_eq!(
  3002. Err(ProgramError::UninitializedAccount),
  3003. do_process_instruction(
  3004. mint_to(
  3005. &program_id,
  3006. &mint_key,
  3007. &uninitialized_key,
  3008. &owner_key,
  3009. &[],
  3010. 42
  3011. )
  3012. .unwrap(),
  3013. vec![
  3014. &mut mint_account,
  3015. &mut uninitialized_account,
  3016. &mut owner_account,
  3017. ],
  3018. &[Check::err(ProgramError::UninitializedAccount)],
  3019. )
  3020. );
  3021. // unset mint_authority and test minting fails
  3022. do_process_instruction(
  3023. set_authority(
  3024. &program_id,
  3025. &mint_key,
  3026. None,
  3027. AuthorityType::MintTokens,
  3028. &owner_key,
  3029. &[],
  3030. )
  3031. .unwrap(),
  3032. vec![&mut mint_account, &mut owner_account],
  3033. &[Check::success()],
  3034. )
  3035. .unwrap();
  3036. assert_eq!(
  3037. Err(TokenError::FixedSupply.into()),
  3038. do_process_instruction(
  3039. mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
  3040. vec![&mut mint_account, &mut account2_account, &mut owner_account],
  3041. &[Check::err(TokenError::FixedSupply.into())],
  3042. )
  3043. );
  3044. }
  3045. #[test]
  3046. fn test_burn_dups() {
  3047. let program_id = spl_token::id();
  3048. let account1_key = Pubkey::new_unique();
  3049. let mut account1_account = SolanaAccount::new(
  3050. account_minimum_balance(),
  3051. Account::get_packed_len(),
  3052. &program_id,
  3053. );
  3054. let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
  3055. let owner_key = Pubkey::new_unique();
  3056. let mut owner_account = SolanaAccount::default();
  3057. let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
  3058. let mint_key = Pubkey::new_unique();
  3059. let mut mint_account =
  3060. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  3061. let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
  3062. let rent_key = rent::id();
  3063. let mut rent_sysvar = rent_sysvar();
  3064. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  3065. // create mint
  3066. do_process_instruction_dups(
  3067. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  3068. vec![mint_info.clone(), rent_info.clone()],
  3069. &[Check::success()],
  3070. )
  3071. .unwrap();
  3072. // create account
  3073. do_process_instruction_dups(
  3074. initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
  3075. vec![
  3076. account1_info.clone(),
  3077. mint_info.clone(),
  3078. account1_info.clone(),
  3079. rent_info.clone(),
  3080. ],
  3081. &[Check::success()],
  3082. )
  3083. .unwrap();
  3084. // mint to account
  3085. do_process_instruction_dups(
  3086. mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
  3087. vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
  3088. &[Check::success()],
  3089. )
  3090. .unwrap();
  3091. // source-owner burn
  3092. do_process_instruction_dups(
  3093. burn(
  3094. &program_id,
  3095. &account1_key,
  3096. &mint_key,
  3097. &account1_key,
  3098. &[],
  3099. 500,
  3100. )
  3101. .unwrap(),
  3102. vec![
  3103. account1_info.clone(),
  3104. mint_info.clone(),
  3105. account1_info.clone(),
  3106. ],
  3107. &[Check::success()],
  3108. )
  3109. .unwrap();
  3110. // source-owner burn_checked
  3111. do_process_instruction_dups(
  3112. burn_checked(
  3113. &program_id,
  3114. &account1_key,
  3115. &mint_key,
  3116. &account1_key,
  3117. &[],
  3118. 500,
  3119. 2,
  3120. )
  3121. .unwrap(),
  3122. vec![
  3123. account1_info.clone(),
  3124. mint_info.clone(),
  3125. account1_info.clone(),
  3126. ],
  3127. &[Check::success()],
  3128. )
  3129. .unwrap();
  3130. // mint-owner burn
  3131. do_process_instruction_dups(
  3132. mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
  3133. vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
  3134. &[Check::success()],
  3135. )
  3136. .unwrap();
  3137. let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
  3138. account.owner = mint_key;
  3139. Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
  3140. do_process_instruction_dups(
  3141. burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
  3142. vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
  3143. &[Check::success()],
  3144. )
  3145. .unwrap();
  3146. // mint-owner burn_checked
  3147. do_process_instruction_dups(
  3148. burn_checked(
  3149. &program_id,
  3150. &account1_key,
  3151. &mint_key,
  3152. &mint_key,
  3153. &[],
  3154. 500,
  3155. 2,
  3156. )
  3157. .unwrap(),
  3158. vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
  3159. &[Check::success()],
  3160. )
  3161. .unwrap();
  3162. // source-delegate burn
  3163. do_process_instruction_dups(
  3164. mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
  3165. vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
  3166. &[Check::success()],
  3167. )
  3168. .unwrap();
  3169. let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
  3170. account.delegated_amount = 1000;
  3171. account.delegate = COption::Some(account1_key);
  3172. account.owner = owner_key;
  3173. Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
  3174. do_process_instruction_dups(
  3175. burn(
  3176. &program_id,
  3177. &account1_key,
  3178. &mint_key,
  3179. &account1_key,
  3180. &[],
  3181. 500,
  3182. )
  3183. .unwrap(),
  3184. vec![
  3185. account1_info.clone(),
  3186. mint_info.clone(),
  3187. account1_info.clone(),
  3188. ],
  3189. &[Check::success()],
  3190. )
  3191. .unwrap();
  3192. // source-delegate burn_checked
  3193. do_process_instruction_dups(
  3194. burn_checked(
  3195. &program_id,
  3196. &account1_key,
  3197. &mint_key,
  3198. &account1_key,
  3199. &[],
  3200. 500,
  3201. 2,
  3202. )
  3203. .unwrap(),
  3204. vec![
  3205. account1_info.clone(),
  3206. mint_info.clone(),
  3207. account1_info.clone(),
  3208. ],
  3209. &[Check::success()],
  3210. )
  3211. .unwrap();
  3212. // mint-delegate burn
  3213. do_process_instruction_dups(
  3214. mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
  3215. vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
  3216. &[Check::success()],
  3217. )
  3218. .unwrap();
  3219. let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
  3220. account.delegated_amount = 1000;
  3221. account.delegate = COption::Some(mint_key);
  3222. account.owner = owner_key;
  3223. Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
  3224. do_process_instruction_dups(
  3225. burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
  3226. vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
  3227. &[Check::success()],
  3228. )
  3229. .unwrap();
  3230. // mint-delegate burn_checked
  3231. do_process_instruction_dups(
  3232. burn_checked(
  3233. &program_id,
  3234. &account1_key,
  3235. &mint_key,
  3236. &mint_key,
  3237. &[],
  3238. 500,
  3239. 2,
  3240. )
  3241. .unwrap(),
  3242. vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
  3243. &[Check::success()],
  3244. )
  3245. .unwrap();
  3246. }
  3247. #[test]
  3248. fn test_burn() {
  3249. let program_id = spl_token::id();
  3250. let account_key = Pubkey::new_unique();
  3251. let mut account_account = SolanaAccount::new(
  3252. account_minimum_balance(),
  3253. Account::get_packed_len(),
  3254. &program_id,
  3255. );
  3256. let account2_key = Pubkey::new_unique();
  3257. let mut account2_account = SolanaAccount::new(
  3258. account_minimum_balance(),
  3259. Account::get_packed_len(),
  3260. &program_id,
  3261. );
  3262. let account3_key = Pubkey::new_unique();
  3263. let mut account3_account = SolanaAccount::new(
  3264. account_minimum_balance(),
  3265. Account::get_packed_len(),
  3266. &program_id,
  3267. );
  3268. let delegate_key = Pubkey::new_unique();
  3269. let mut delegate_account = SolanaAccount::default();
  3270. let mismatch_key = Pubkey::new_unique();
  3271. let mut mismatch_account = SolanaAccount::new(
  3272. account_minimum_balance(),
  3273. Account::get_packed_len(),
  3274. &program_id,
  3275. );
  3276. let owner_key = Pubkey::new_unique();
  3277. let mut owner_account = SolanaAccount::default();
  3278. let owner2_key = Pubkey::new_unique();
  3279. let mut owner2_account = SolanaAccount::default();
  3280. let mint_key = Pubkey::new_unique();
  3281. let mut mint_account =
  3282. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  3283. let mint2_key = Pubkey::new_unique();
  3284. let mut rent_sysvar = rent_sysvar();
  3285. // create new mint
  3286. do_process_instruction(
  3287. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  3288. vec![&mut mint_account, &mut rent_sysvar],
  3289. &[Check::success()],
  3290. )
  3291. .unwrap();
  3292. // create account
  3293. do_process_instruction(
  3294. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  3295. vec![
  3296. &mut account_account,
  3297. &mut mint_account,
  3298. &mut owner_account,
  3299. &mut rent_sysvar,
  3300. ],
  3301. &[Check::success()],
  3302. )
  3303. .unwrap();
  3304. // create another account
  3305. do_process_instruction(
  3306. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  3307. vec![
  3308. &mut account2_account,
  3309. &mut mint_account,
  3310. &mut owner_account,
  3311. &mut rent_sysvar,
  3312. ],
  3313. &[Check::success()],
  3314. )
  3315. .unwrap();
  3316. // create another account
  3317. do_process_instruction(
  3318. initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
  3319. vec![
  3320. &mut account3_account,
  3321. &mut mint_account,
  3322. &mut owner_account,
  3323. &mut rent_sysvar,
  3324. ],
  3325. &[Check::success()],
  3326. )
  3327. .unwrap();
  3328. // create mismatch account
  3329. do_process_instruction(
  3330. initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
  3331. vec![
  3332. &mut mismatch_account,
  3333. &mut mint_account,
  3334. &mut owner_account,
  3335. &mut rent_sysvar,
  3336. ],
  3337. &[Check::success()],
  3338. )
  3339. .unwrap();
  3340. // mint to account
  3341. do_process_instruction(
  3342. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  3343. vec![&mut mint_account, &mut account_account, &mut owner_account],
  3344. &[Check::success()],
  3345. )
  3346. .unwrap();
  3347. // mint to mismatch account and change mint key
  3348. do_process_instruction(
  3349. mint_to(&program_id, &mint_key, &mismatch_key, &owner_key, &[], 1000).unwrap(),
  3350. vec![&mut mint_account, &mut mismatch_account, &mut owner_account],
  3351. &[Check::success()],
  3352. )
  3353. .unwrap();
  3354. let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
  3355. account.mint = mint2_key;
  3356. Account::pack(account, &mut mismatch_account.data).unwrap();
  3357. // missing signer
  3358. let mut instruction =
  3359. burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 42).unwrap();
  3360. instruction.accounts[1].is_signer = false;
  3361. assert_eq!(
  3362. Err(TokenError::OwnerMismatch.into()),
  3363. do_process_instruction(
  3364. instruction,
  3365. vec![
  3366. &mut account_account,
  3367. &mut mint_account,
  3368. &mut delegate_account
  3369. ],
  3370. &[Check::err(TokenError::OwnerMismatch.into())],
  3371. )
  3372. );
  3373. // missing owner
  3374. assert_eq!(
  3375. Err(TokenError::OwnerMismatch.into()),
  3376. do_process_instruction(
  3377. burn(&program_id, &account_key, &mint_key, &owner2_key, &[], 42).unwrap(),
  3378. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  3379. &[Check::err(TokenError::OwnerMismatch.into())],
  3380. )
  3381. );
  3382. // account not owned by program
  3383. let not_program_id = Pubkey::new_unique();
  3384. account_account.owner = not_program_id;
  3385. assert_eq!(
  3386. Err(ProgramError::IncorrectProgramId),
  3387. do_process_instruction(
  3388. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 0).unwrap(),
  3389. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3390. &[Check::err(ProgramError::IncorrectProgramId)],
  3391. )
  3392. );
  3393. account_account.owner = program_id;
  3394. // mint not owned by program
  3395. let not_program_id = Pubkey::new_unique();
  3396. mint_account.owner = not_program_id;
  3397. assert_eq!(
  3398. Err(ProgramError::IncorrectProgramId),
  3399. do_process_instruction(
  3400. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 0).unwrap(),
  3401. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3402. &[Check::err(ProgramError::IncorrectProgramId)],
  3403. )
  3404. );
  3405. mint_account.owner = program_id;
  3406. // mint mismatch
  3407. assert_eq!(
  3408. Err(TokenError::MintMismatch.into()),
  3409. do_process_instruction(
  3410. burn(&program_id, &mismatch_key, &mint_key, &owner_key, &[], 42).unwrap(),
  3411. vec![&mut mismatch_account, &mut mint_account, &mut owner_account],
  3412. &[Check::err(TokenError::MintMismatch.into())],
  3413. )
  3414. );
  3415. // burn
  3416. do_process_instruction(
  3417. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 21).unwrap(),
  3418. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3419. &[Check::success()],
  3420. )
  3421. .unwrap();
  3422. // burn_checked, with incorrect decimals
  3423. assert_eq!(
  3424. Err(TokenError::MintDecimalsMismatch.into()),
  3425. do_process_instruction(
  3426. burn_checked(&program_id, &account_key, &mint_key, &owner_key, &[], 21, 3).unwrap(),
  3427. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3428. &[Check::err(TokenError::MintDecimalsMismatch.into())],
  3429. )
  3430. );
  3431. // burn_checked
  3432. do_process_instruction(
  3433. burn_checked(&program_id, &account_key, &mint_key, &owner_key, &[], 21, 2).unwrap(),
  3434. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3435. &[
  3436. Check::success(),
  3437. Check::account(&mint_key)
  3438. .data_slice(36, &(2000u64 - 42).to_le_bytes())
  3439. .build(),
  3440. Check::account(&account_key)
  3441. .data_slice(64, &(1000u64 - 42).to_le_bytes())
  3442. .build(),
  3443. ],
  3444. )
  3445. .unwrap();
  3446. let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
  3447. assert_eq!(mint.supply, 2000 - 42);
  3448. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  3449. assert_eq!(account.amount, 1000 - 42);
  3450. // insufficient funds
  3451. assert_eq!(
  3452. Err(TokenError::InsufficientFunds.into()),
  3453. do_process_instruction(
  3454. burn(
  3455. &program_id,
  3456. &account_key,
  3457. &mint_key,
  3458. &owner_key,
  3459. &[],
  3460. 100_000_000
  3461. )
  3462. .unwrap(),
  3463. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3464. &[Check::err(TokenError::InsufficientFunds.into())],
  3465. )
  3466. );
  3467. // approve delegate
  3468. do_process_instruction(
  3469. approve(
  3470. &program_id,
  3471. &account_key,
  3472. &delegate_key,
  3473. &owner_key,
  3474. &[],
  3475. 84,
  3476. )
  3477. .unwrap(),
  3478. vec![
  3479. &mut account_account,
  3480. &mut delegate_account,
  3481. &mut owner_account,
  3482. ],
  3483. &[Check::success()],
  3484. )
  3485. .unwrap();
  3486. // not a delegate of source account
  3487. assert_eq!(
  3488. Err(TokenError::OwnerMismatch.into()),
  3489. do_process_instruction(
  3490. burn(
  3491. &program_id,
  3492. &account_key,
  3493. &mint_key,
  3494. &owner2_key, // <-- incorrect owner or delegate
  3495. &[],
  3496. 1,
  3497. )
  3498. .unwrap(),
  3499. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  3500. &[Check::err(TokenError::OwnerMismatch.into())],
  3501. )
  3502. );
  3503. // insufficient funds approved via delegate
  3504. assert_eq!(
  3505. Err(TokenError::InsufficientFunds.into()),
  3506. do_process_instruction(
  3507. burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 85).unwrap(),
  3508. vec![
  3509. &mut account_account,
  3510. &mut mint_account,
  3511. &mut delegate_account
  3512. ],
  3513. &[Check::err(TokenError::InsufficientFunds.into())],
  3514. )
  3515. );
  3516. // burn via delegate
  3517. do_process_instruction(
  3518. burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 84).unwrap(),
  3519. vec![
  3520. &mut account_account,
  3521. &mut mint_account,
  3522. &mut delegate_account,
  3523. ],
  3524. &[
  3525. Check::success(),
  3526. Check::account(&mint_key)
  3527. .data_slice(36, &(2000u64 - 42 - 84).to_le_bytes())
  3528. .build(),
  3529. Check::account(&account_key)
  3530. .data_slice(64, &(1000u64 - 42 - 84).to_le_bytes())
  3531. .build(),
  3532. ],
  3533. )
  3534. .unwrap();
  3535. // match
  3536. let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
  3537. assert_eq!(mint.supply, 2000 - 42 - 84);
  3538. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  3539. assert_eq!(account.amount, 1000 - 42 - 84);
  3540. // insufficient funds approved via delegate
  3541. assert_eq!(
  3542. Err(TokenError::OwnerMismatch.into()),
  3543. do_process_instruction(
  3544. burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 1).unwrap(),
  3545. vec![
  3546. &mut account_account,
  3547. &mut mint_account,
  3548. &mut delegate_account
  3549. ],
  3550. &[Check::err(TokenError::OwnerMismatch.into())],
  3551. )
  3552. );
  3553. }
  3554. #[test]
  3555. fn test_burn_and_close_system_and_incinerator_tokens() {
  3556. let program_id = spl_token::id();
  3557. let account_key = Pubkey::new_unique();
  3558. let mut account_account = SolanaAccount::new(
  3559. account_minimum_balance(),
  3560. Account::get_packed_len(),
  3561. &program_id,
  3562. );
  3563. let incinerator_account_key = Pubkey::new_unique();
  3564. let mut incinerator_account = SolanaAccount::new(
  3565. account_minimum_balance(),
  3566. Account::get_packed_len(),
  3567. &program_id,
  3568. );
  3569. let system_account_key = Pubkey::new_unique();
  3570. let mut system_account = SolanaAccount::new(
  3571. account_minimum_balance(),
  3572. Account::get_packed_len(),
  3573. &program_id,
  3574. );
  3575. let owner_key = Pubkey::new_unique();
  3576. let mut owner_account = SolanaAccount::default();
  3577. let recipient_key = Pubkey::new_unique();
  3578. let mut recipient_account = SolanaAccount::default();
  3579. let mut mock_incinerator_account = SolanaAccount::default();
  3580. let mint_key = Pubkey::new_unique();
  3581. let mut mint_account =
  3582. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  3583. // create new mint
  3584. do_process_instruction(
  3585. initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  3586. vec![&mut mint_account],
  3587. &[Check::success()],
  3588. )
  3589. .unwrap();
  3590. // create account
  3591. do_process_instruction(
  3592. initialize_account3(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  3593. vec![&mut account_account, &mut mint_account],
  3594. &[Check::success()],
  3595. )
  3596. .unwrap();
  3597. // create incinerator- and system-owned accounts
  3598. do_process_instruction(
  3599. initialize_account3(
  3600. &program_id,
  3601. &incinerator_account_key,
  3602. &mint_key,
  3603. &solana_program::incinerator::id(),
  3604. )
  3605. .unwrap(),
  3606. vec![&mut incinerator_account, &mut mint_account],
  3607. &[Check::success()],
  3608. )
  3609. .unwrap();
  3610. do_process_instruction(
  3611. initialize_account3(
  3612. &program_id,
  3613. &system_account_key,
  3614. &mint_key,
  3615. &solana_program::system_program::id(),
  3616. )
  3617. .unwrap(),
  3618. vec![&mut system_account, &mut mint_account],
  3619. &[Check::success()],
  3620. )
  3621. .unwrap();
  3622. // mint to account
  3623. do_process_instruction(
  3624. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  3625. vec![&mut mint_account, &mut account_account, &mut owner_account],
  3626. &[Check::success()],
  3627. )
  3628. .unwrap();
  3629. // transfer half to incinerator, half to system program
  3630. do_process_instruction(
  3631. transfer(
  3632. &program_id,
  3633. &account_key,
  3634. &incinerator_account_key,
  3635. &owner_key,
  3636. &[],
  3637. 500,
  3638. )
  3639. .unwrap(),
  3640. vec![
  3641. &mut account_account,
  3642. &mut incinerator_account,
  3643. &mut owner_account,
  3644. ],
  3645. &[Check::success()],
  3646. )
  3647. .unwrap();
  3648. do_process_instruction(
  3649. transfer(
  3650. &program_id,
  3651. &account_key,
  3652. &system_account_key,
  3653. &owner_key,
  3654. &[],
  3655. 500,
  3656. )
  3657. .unwrap(),
  3658. vec![
  3659. &mut account_account,
  3660. &mut system_account,
  3661. &mut owner_account,
  3662. ],
  3663. &[Check::success()],
  3664. )
  3665. .unwrap();
  3666. // close with balance fails
  3667. assert_eq!(
  3668. Err(TokenError::NonNativeHasBalance.into()),
  3669. do_process_instruction(
  3670. close_account(
  3671. &program_id,
  3672. &incinerator_account_key,
  3673. &solana_program::incinerator::id(),
  3674. &owner_key,
  3675. &[]
  3676. )
  3677. .unwrap(),
  3678. vec![
  3679. &mut incinerator_account,
  3680. &mut mock_incinerator_account,
  3681. &mut owner_account,
  3682. ],
  3683. &[Check::err(TokenError::NonNativeHasBalance.into())],
  3684. )
  3685. );
  3686. assert_eq!(
  3687. Err(TokenError::NonNativeHasBalance.into()),
  3688. do_process_instruction(
  3689. close_account(
  3690. &program_id,
  3691. &system_account_key,
  3692. &solana_program::incinerator::id(),
  3693. &owner_key,
  3694. &[]
  3695. )
  3696. .unwrap(),
  3697. vec![
  3698. &mut system_account,
  3699. &mut mock_incinerator_account,
  3700. &mut owner_account,
  3701. ],
  3702. &[Check::err(TokenError::NonNativeHasBalance.into())],
  3703. )
  3704. );
  3705. // anyone can burn
  3706. do_process_instruction(
  3707. burn(
  3708. &program_id,
  3709. &incinerator_account_key,
  3710. &mint_key,
  3711. &recipient_key,
  3712. &[],
  3713. 500,
  3714. )
  3715. .unwrap(),
  3716. vec![
  3717. &mut incinerator_account,
  3718. &mut mint_account,
  3719. &mut recipient_account,
  3720. ],
  3721. &[Check::success()],
  3722. )
  3723. .unwrap();
  3724. do_process_instruction(
  3725. burn(
  3726. &program_id,
  3727. &system_account_key,
  3728. &mint_key,
  3729. &recipient_key,
  3730. &[],
  3731. 500,
  3732. )
  3733. .unwrap(),
  3734. vec![
  3735. &mut system_account,
  3736. &mut mint_account,
  3737. &mut recipient_account,
  3738. ],
  3739. &[Check::success()],
  3740. )
  3741. .unwrap();
  3742. // closing fails if destination is not the incinerator
  3743. assert_eq!(
  3744. Err(ProgramError::InvalidAccountData),
  3745. do_process_instruction(
  3746. close_account(
  3747. &program_id,
  3748. &incinerator_account_key,
  3749. &recipient_key,
  3750. &owner_key,
  3751. &[]
  3752. )
  3753. .unwrap(),
  3754. vec![
  3755. &mut incinerator_account,
  3756. &mut recipient_account,
  3757. &mut owner_account,
  3758. ],
  3759. &[Check::err(ProgramError::InvalidAccountData)],
  3760. )
  3761. );
  3762. assert_eq!(
  3763. Err(ProgramError::InvalidAccountData),
  3764. do_process_instruction(
  3765. close_account(
  3766. &program_id,
  3767. &system_account_key,
  3768. &recipient_key,
  3769. &owner_key,
  3770. &[]
  3771. )
  3772. .unwrap(),
  3773. vec![
  3774. &mut system_account,
  3775. &mut recipient_account,
  3776. &mut owner_account,
  3777. ],
  3778. &[Check::err(ProgramError::InvalidAccountData)],
  3779. )
  3780. );
  3781. // closing succeeds with incinerator recipient
  3782. do_process_instruction(
  3783. close_account(
  3784. &program_id,
  3785. &incinerator_account_key,
  3786. &solana_program::incinerator::id(),
  3787. &owner_key,
  3788. &[],
  3789. )
  3790. .unwrap(),
  3791. vec![
  3792. &mut incinerator_account,
  3793. &mut mock_incinerator_account,
  3794. &mut owner_account,
  3795. ],
  3796. &[Check::success()],
  3797. )
  3798. .unwrap();
  3799. do_process_instruction(
  3800. close_account(
  3801. &program_id,
  3802. &system_account_key,
  3803. &solana_program::incinerator::id(),
  3804. &owner_key,
  3805. &[],
  3806. )
  3807. .unwrap(),
  3808. vec![
  3809. &mut system_account,
  3810. &mut mock_incinerator_account,
  3811. &mut owner_account,
  3812. ],
  3813. &[Check::success()],
  3814. )
  3815. .unwrap();
  3816. }
  3817. #[test]
  3818. fn test_multisig() {
  3819. let program_id = spl_token::id();
  3820. let mint_key = Pubkey::new_unique();
  3821. let mut mint_account =
  3822. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  3823. let account_key = Pubkey::new_unique();
  3824. let mut account = SolanaAccount::new(
  3825. account_minimum_balance(),
  3826. Account::get_packed_len(),
  3827. &program_id,
  3828. );
  3829. let account2_key = Pubkey::new_unique();
  3830. let mut account2_account = SolanaAccount::new(
  3831. account_minimum_balance(),
  3832. Account::get_packed_len(),
  3833. &program_id,
  3834. );
  3835. let owner_key = Pubkey::new_unique();
  3836. let mut owner_account = SolanaAccount::default();
  3837. let multisig_key = Pubkey::new_unique();
  3838. let mut multisig_account = SolanaAccount::new(42, Multisig::get_packed_len(), &program_id);
  3839. let multisig_delegate_key = Pubkey::new_unique();
  3840. let mut multisig_delegate_account = SolanaAccount::new(
  3841. multisig_minimum_balance(),
  3842. Multisig::get_packed_len(),
  3843. &program_id,
  3844. );
  3845. let signer_keys = vec![Pubkey::new_unique(); MAX_SIGNERS];
  3846. let signer_key_refs: Vec<&Pubkey> = signer_keys.iter().collect();
  3847. let mut signer_accounts = vec![SolanaAccount::new(0, 0, &program_id); MAX_SIGNERS];
  3848. let mut rent_sysvar = rent_sysvar();
  3849. // multisig is not rent exempt
  3850. let account_info_iter = &mut signer_accounts.iter_mut();
  3851. assert_eq!(
  3852. Err(TokenError::NotRentExempt.into()),
  3853. do_process_instruction(
  3854. initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
  3855. vec![
  3856. &mut multisig_account,
  3857. &mut rent_sysvar,
  3858. account_info_iter.next().unwrap(),
  3859. ],
  3860. &[Check::err(TokenError::NotRentExempt.into())],
  3861. )
  3862. );
  3863. multisig_account.lamports = multisig_minimum_balance();
  3864. let mut multisig_account2 = multisig_account.clone();
  3865. // single signer
  3866. let account_info_iter = &mut signer_accounts.iter_mut();
  3867. do_process_instruction(
  3868. initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
  3869. vec![
  3870. &mut multisig_account,
  3871. &mut rent_sysvar,
  3872. account_info_iter.next().unwrap(),
  3873. ],
  3874. &[Check::success()],
  3875. )
  3876. .unwrap();
  3877. // single signer using `initialize_multisig2`
  3878. let account_info_iter = &mut signer_accounts.iter_mut();
  3879. do_process_instruction(
  3880. initialize_multisig2(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
  3881. vec![&mut multisig_account2, account_info_iter.next().unwrap()],
  3882. &[Check::success()],
  3883. )
  3884. .unwrap();
  3885. // multiple signer
  3886. let account_info_iter = &mut signer_accounts.iter_mut();
  3887. do_process_instruction(
  3888. initialize_multisig(
  3889. &program_id,
  3890. &multisig_delegate_key,
  3891. &signer_key_refs,
  3892. MAX_SIGNERS as u8,
  3893. )
  3894. .unwrap(),
  3895. vec![
  3896. &mut multisig_delegate_account,
  3897. &mut rent_sysvar,
  3898. account_info_iter.next().unwrap(),
  3899. account_info_iter.next().unwrap(),
  3900. account_info_iter.next().unwrap(),
  3901. account_info_iter.next().unwrap(),
  3902. account_info_iter.next().unwrap(),
  3903. account_info_iter.next().unwrap(),
  3904. account_info_iter.next().unwrap(),
  3905. account_info_iter.next().unwrap(),
  3906. account_info_iter.next().unwrap(),
  3907. account_info_iter.next().unwrap(),
  3908. account_info_iter.next().unwrap(),
  3909. ],
  3910. &[Check::success()],
  3911. )
  3912. .unwrap();
  3913. // create new mint with multisig owner
  3914. do_process_instruction(
  3915. initialize_mint(&program_id, &mint_key, &multisig_key, None, 2).unwrap(),
  3916. vec![&mut mint_account, &mut rent_sysvar],
  3917. &[Check::success()],
  3918. )
  3919. .unwrap();
  3920. // create account with multisig owner
  3921. do_process_instruction(
  3922. initialize_account(&program_id, &account_key, &mint_key, &multisig_key).unwrap(),
  3923. vec![
  3924. &mut account,
  3925. &mut mint_account,
  3926. &mut multisig_account,
  3927. &mut rent_sysvar,
  3928. ],
  3929. &[Check::success()],
  3930. )
  3931. .unwrap();
  3932. // create another account with multisig owner
  3933. do_process_instruction(
  3934. initialize_account(
  3935. &program_id,
  3936. &account2_key,
  3937. &mint_key,
  3938. &multisig_delegate_key,
  3939. )
  3940. .unwrap(),
  3941. vec![
  3942. &mut account2_account,
  3943. &mut mint_account,
  3944. &mut multisig_account,
  3945. &mut rent_sysvar,
  3946. ],
  3947. &[Check::success()],
  3948. )
  3949. .unwrap();
  3950. // mint to account
  3951. let account_info_iter = &mut signer_accounts.iter_mut();
  3952. do_process_instruction(
  3953. mint_to(
  3954. &program_id,
  3955. &mint_key,
  3956. &account_key,
  3957. &multisig_key,
  3958. &[&signer_keys[0]],
  3959. 1000,
  3960. )
  3961. .unwrap(),
  3962. vec![
  3963. &mut mint_account,
  3964. &mut account,
  3965. &mut multisig_account,
  3966. account_info_iter.next().unwrap(),
  3967. ],
  3968. &[Check::success()],
  3969. )
  3970. .unwrap();
  3971. // approve
  3972. let account_info_iter = &mut signer_accounts.iter_mut();
  3973. do_process_instruction(
  3974. approve(
  3975. &program_id,
  3976. &account_key,
  3977. &multisig_delegate_key,
  3978. &multisig_key,
  3979. &[&signer_keys[0]],
  3980. 100,
  3981. )
  3982. .unwrap(),
  3983. vec![
  3984. &mut account,
  3985. &mut multisig_delegate_account,
  3986. &mut multisig_account,
  3987. account_info_iter.next().unwrap(),
  3988. ],
  3989. &[Check::success()],
  3990. )
  3991. .unwrap();
  3992. // transfer
  3993. let account_info_iter = &mut signer_accounts.iter_mut();
  3994. do_process_instruction(
  3995. transfer(
  3996. &program_id,
  3997. &account_key,
  3998. &account2_key,
  3999. &multisig_key,
  4000. &[&signer_keys[0]],
  4001. 42,
  4002. )
  4003. .unwrap(),
  4004. vec![
  4005. &mut account,
  4006. &mut account2_account,
  4007. &mut multisig_account,
  4008. account_info_iter.next().unwrap(),
  4009. ],
  4010. &[Check::success()],
  4011. )
  4012. .unwrap();
  4013. // transfer via delegate
  4014. let account_info_iter = &mut signer_accounts.iter_mut();
  4015. do_process_instruction(
  4016. transfer(
  4017. &program_id,
  4018. &account_key,
  4019. &account2_key,
  4020. &multisig_delegate_key,
  4021. &signer_key_refs,
  4022. 42,
  4023. )
  4024. .unwrap(),
  4025. vec![
  4026. &mut account,
  4027. &mut account2_account,
  4028. &mut multisig_delegate_account,
  4029. account_info_iter.next().unwrap(),
  4030. account_info_iter.next().unwrap(),
  4031. account_info_iter.next().unwrap(),
  4032. account_info_iter.next().unwrap(),
  4033. account_info_iter.next().unwrap(),
  4034. account_info_iter.next().unwrap(),
  4035. account_info_iter.next().unwrap(),
  4036. account_info_iter.next().unwrap(),
  4037. account_info_iter.next().unwrap(),
  4038. account_info_iter.next().unwrap(),
  4039. account_info_iter.next().unwrap(),
  4040. ],
  4041. &[Check::success()],
  4042. )
  4043. .unwrap();
  4044. // mint to
  4045. let account_info_iter = &mut signer_accounts.iter_mut();
  4046. do_process_instruction(
  4047. mint_to(
  4048. &program_id,
  4049. &mint_key,
  4050. &account2_key,
  4051. &multisig_key,
  4052. &[&signer_keys[0]],
  4053. 42,
  4054. )
  4055. .unwrap(),
  4056. vec![
  4057. &mut mint_account,
  4058. &mut account2_account,
  4059. &mut multisig_account,
  4060. account_info_iter.next().unwrap(),
  4061. ],
  4062. &[Check::success()],
  4063. )
  4064. .unwrap();
  4065. // burn
  4066. let account_info_iter = &mut signer_accounts.iter_mut();
  4067. do_process_instruction(
  4068. burn(
  4069. &program_id,
  4070. &account_key,
  4071. &mint_key,
  4072. &multisig_key,
  4073. &[&signer_keys[0]],
  4074. 42,
  4075. )
  4076. .unwrap(),
  4077. vec![
  4078. &mut account,
  4079. &mut mint_account,
  4080. &mut multisig_account,
  4081. account_info_iter.next().unwrap(),
  4082. ],
  4083. &[Check::success()],
  4084. )
  4085. .unwrap();
  4086. // burn via delegate
  4087. let account_info_iter = &mut signer_accounts.iter_mut();
  4088. do_process_instruction(
  4089. burn(
  4090. &program_id,
  4091. &account_key,
  4092. &mint_key,
  4093. &multisig_delegate_key,
  4094. &signer_key_refs,
  4095. 42,
  4096. )
  4097. .unwrap(),
  4098. vec![
  4099. &mut account,
  4100. &mut mint_account,
  4101. &mut multisig_delegate_account,
  4102. account_info_iter.next().unwrap(),
  4103. account_info_iter.next().unwrap(),
  4104. account_info_iter.next().unwrap(),
  4105. account_info_iter.next().unwrap(),
  4106. account_info_iter.next().unwrap(),
  4107. account_info_iter.next().unwrap(),
  4108. account_info_iter.next().unwrap(),
  4109. account_info_iter.next().unwrap(),
  4110. account_info_iter.next().unwrap(),
  4111. account_info_iter.next().unwrap(),
  4112. account_info_iter.next().unwrap(),
  4113. ],
  4114. &[Check::success()],
  4115. )
  4116. .unwrap();
  4117. // freeze account
  4118. let account3_key = Pubkey::new_unique();
  4119. let mut account3_account = SolanaAccount::new(
  4120. account_minimum_balance(),
  4121. Account::get_packed_len(),
  4122. &program_id,
  4123. );
  4124. let mint2_key = Pubkey::new_unique();
  4125. let mut mint2_account =
  4126. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  4127. do_process_instruction(
  4128. initialize_mint(
  4129. &program_id,
  4130. &mint2_key,
  4131. &multisig_key,
  4132. Some(&multisig_key),
  4133. 2,
  4134. )
  4135. .unwrap(),
  4136. vec![&mut mint2_account, &mut rent_sysvar],
  4137. &[Check::success()],
  4138. )
  4139. .unwrap();
  4140. do_process_instruction(
  4141. initialize_account(&program_id, &account3_key, &mint2_key, &owner_key).unwrap(),
  4142. vec![
  4143. &mut account3_account,
  4144. &mut mint2_account,
  4145. &mut owner_account,
  4146. &mut rent_sysvar,
  4147. ],
  4148. &[Check::success()],
  4149. )
  4150. .unwrap();
  4151. let account_info_iter = &mut signer_accounts.iter_mut();
  4152. do_process_instruction(
  4153. mint_to(
  4154. &program_id,
  4155. &mint2_key,
  4156. &account3_key,
  4157. &multisig_key,
  4158. &[&signer_keys[0]],
  4159. 1000,
  4160. )
  4161. .unwrap(),
  4162. vec![
  4163. &mut mint2_account,
  4164. &mut account3_account,
  4165. &mut multisig_account,
  4166. account_info_iter.next().unwrap(),
  4167. ],
  4168. &[Check::success()],
  4169. )
  4170. .unwrap();
  4171. let account_info_iter = &mut signer_accounts.iter_mut();
  4172. do_process_instruction(
  4173. freeze_account(
  4174. &program_id,
  4175. &account3_key,
  4176. &mint2_key,
  4177. &multisig_key,
  4178. &[&signer_keys[0]],
  4179. )
  4180. .unwrap(),
  4181. vec![
  4182. &mut account3_account,
  4183. &mut mint2_account,
  4184. &mut multisig_account,
  4185. account_info_iter.next().unwrap(),
  4186. ],
  4187. &[Check::success()],
  4188. )
  4189. .unwrap();
  4190. // do SetAuthority on mint
  4191. let account_info_iter = &mut signer_accounts.iter_mut();
  4192. do_process_instruction(
  4193. set_authority(
  4194. &program_id,
  4195. &mint_key,
  4196. Some(&owner_key),
  4197. AuthorityType::MintTokens,
  4198. &multisig_key,
  4199. &[&signer_keys[0]],
  4200. )
  4201. .unwrap(),
  4202. vec![
  4203. &mut mint_account,
  4204. &mut multisig_account,
  4205. account_info_iter.next().unwrap(),
  4206. ],
  4207. &[Check::success()],
  4208. )
  4209. .unwrap();
  4210. // do SetAuthority on account
  4211. let account_info_iter = &mut signer_accounts.iter_mut();
  4212. do_process_instruction(
  4213. set_authority(
  4214. &program_id,
  4215. &account_key,
  4216. Some(&owner_key),
  4217. AuthorityType::AccountOwner,
  4218. &multisig_key,
  4219. &[&signer_keys[0]],
  4220. )
  4221. .unwrap(),
  4222. vec![
  4223. &mut account,
  4224. &mut multisig_account,
  4225. account_info_iter.next().unwrap(),
  4226. ],
  4227. &[Check::success()],
  4228. )
  4229. .unwrap();
  4230. }
  4231. #[test]
  4232. fn test_owner_close_account_dups() {
  4233. let program_id = spl_token::id();
  4234. let owner_key = Pubkey::new_unique();
  4235. let mint_key = Pubkey::new_unique();
  4236. let mut mint_account =
  4237. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  4238. let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
  4239. let rent_key = rent::id();
  4240. let mut rent_sysvar = rent_sysvar();
  4241. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  4242. // create mint
  4243. do_process_instruction_dups(
  4244. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  4245. vec![mint_info.clone(), rent_info.clone()],
  4246. &[Check::success()],
  4247. )
  4248. .unwrap();
  4249. let to_close_key = Pubkey::new_unique();
  4250. let mut to_close_account = SolanaAccount::new(
  4251. account_minimum_balance(),
  4252. Account::get_packed_len(),
  4253. &program_id,
  4254. );
  4255. let to_close_account_info: AccountInfo = (&to_close_key, true, &mut to_close_account).into();
  4256. let destination_account_key = Pubkey::new_unique();
  4257. let mut destination_account = SolanaAccount::new(
  4258. account_minimum_balance(),
  4259. Account::get_packed_len(),
  4260. &program_id,
  4261. );
  4262. let destination_account_info: AccountInfo =
  4263. (&destination_account_key, true, &mut destination_account).into();
  4264. // create account
  4265. do_process_instruction_dups(
  4266. initialize_account(&program_id, &to_close_key, &mint_key, &to_close_key).unwrap(),
  4267. vec![
  4268. to_close_account_info.clone(),
  4269. mint_info.clone(),
  4270. to_close_account_info.clone(),
  4271. rent_info.clone(),
  4272. ],
  4273. &[Check::success()],
  4274. )
  4275. .unwrap();
  4276. // source-owner close
  4277. do_process_instruction_dups(
  4278. close_account(
  4279. &program_id,
  4280. &to_close_key,
  4281. &destination_account_key,
  4282. &to_close_key,
  4283. &[],
  4284. )
  4285. .unwrap(),
  4286. vec![
  4287. to_close_account_info.clone(),
  4288. destination_account_info.clone(),
  4289. to_close_account_info.clone(),
  4290. ],
  4291. &[
  4292. Check::success(),
  4293. Check::account(&to_close_key).data(&[]).build(),
  4294. ],
  4295. )
  4296. .unwrap();
  4297. assert_eq!(*to_close_account_info.data.borrow(), &[0u8; Account::LEN]);
  4298. }
  4299. #[test]
  4300. fn test_close_authority_close_account_dups() {
  4301. let program_id = spl_token::id();
  4302. let owner_key = Pubkey::new_unique();
  4303. let mint_key = Pubkey::new_unique();
  4304. let mut mint_account =
  4305. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  4306. let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
  4307. let rent_key = rent::id();
  4308. let mut rent_sysvar = rent_sysvar();
  4309. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  4310. // create mint
  4311. do_process_instruction_dups(
  4312. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  4313. vec![mint_info.clone(), rent_info.clone()],
  4314. &[Check::success()],
  4315. )
  4316. .unwrap();
  4317. let to_close_key = Pubkey::new_unique();
  4318. let mut to_close_account = SolanaAccount::new(
  4319. account_minimum_balance(),
  4320. Account::get_packed_len(),
  4321. &program_id,
  4322. );
  4323. let to_close_account_info: AccountInfo = (&to_close_key, true, &mut to_close_account).into();
  4324. let destination_account_key = Pubkey::new_unique();
  4325. let mut destination_account = SolanaAccount::new(
  4326. account_minimum_balance(),
  4327. Account::get_packed_len(),
  4328. &program_id,
  4329. );
  4330. let destination_account_info: AccountInfo =
  4331. (&destination_account_key, true, &mut destination_account).into();
  4332. // create account
  4333. do_process_instruction_dups(
  4334. initialize_account(&program_id, &to_close_key, &mint_key, &to_close_key).unwrap(),
  4335. vec![
  4336. to_close_account_info.clone(),
  4337. mint_info.clone(),
  4338. to_close_account_info.clone(),
  4339. rent_info.clone(),
  4340. ],
  4341. &[Check::success()],
  4342. )
  4343. .unwrap();
  4344. let mut account = Account::unpack_unchecked(&to_close_account_info.data.borrow()).unwrap();
  4345. account.close_authority = COption::Some(to_close_key);
  4346. account.owner = owner_key;
  4347. Account::pack(account, &mut to_close_account_info.data.borrow_mut()).unwrap();
  4348. do_process_instruction_dups(
  4349. close_account(
  4350. &program_id,
  4351. &to_close_key,
  4352. &destination_account_key,
  4353. &to_close_key,
  4354. &[],
  4355. )
  4356. .unwrap(),
  4357. vec![
  4358. to_close_account_info.clone(),
  4359. destination_account_info.clone(),
  4360. to_close_account_info.clone(),
  4361. ],
  4362. &[
  4363. Check::success(),
  4364. Check::account(&to_close_key).data(&[]).build(),
  4365. ],
  4366. )
  4367. .unwrap();
  4368. assert_eq!(*to_close_account_info.data.borrow(), &[0u8; Account::LEN]);
  4369. }
  4370. #[test]
  4371. fn test_close_account() {
  4372. let program_id = spl_token::id();
  4373. let mint_key = Pubkey::new_unique();
  4374. let mut mint_account =
  4375. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  4376. let account_key = Pubkey::new_unique();
  4377. let mut account_account = SolanaAccount::new(
  4378. account_minimum_balance(),
  4379. Account::get_packed_len(),
  4380. &program_id,
  4381. );
  4382. let account2_key = Pubkey::new_unique();
  4383. let mut account2_account = SolanaAccount::new(
  4384. account_minimum_balance() + 42,
  4385. Account::get_packed_len(),
  4386. &program_id,
  4387. );
  4388. let account3_key = Pubkey::new_unique();
  4389. let mut account3_account = SolanaAccount::new(
  4390. account_minimum_balance(),
  4391. Account::get_packed_len(),
  4392. &program_id,
  4393. );
  4394. let owner_key = Pubkey::new_unique();
  4395. let mut owner_account = SolanaAccount::default();
  4396. let owner2_key = Pubkey::new_unique();
  4397. let mut owner2_account = SolanaAccount::default();
  4398. let mut rent_sysvar = rent_sysvar();
  4399. // uninitialized
  4400. assert_eq!(
  4401. Err(ProgramError::UninitializedAccount),
  4402. do_process_instruction(
  4403. close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
  4404. vec![
  4405. &mut account_account,
  4406. &mut account3_account,
  4407. &mut owner2_account,
  4408. ],
  4409. &[Check::err(ProgramError::UninitializedAccount)],
  4410. )
  4411. );
  4412. // initialize and mint to non-native account
  4413. do_process_instruction(
  4414. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  4415. vec![&mut mint_account, &mut rent_sysvar],
  4416. &[Check::success()],
  4417. )
  4418. .unwrap();
  4419. do_process_instruction(
  4420. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  4421. vec![
  4422. &mut account_account,
  4423. &mut mint_account,
  4424. &mut owner_account,
  4425. &mut rent_sysvar,
  4426. ],
  4427. &[Check::success()],
  4428. )
  4429. .unwrap();
  4430. do_process_instruction(
  4431. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
  4432. vec![
  4433. &mut mint_account,
  4434. &mut account_account,
  4435. &mut owner_account,
  4436. &mut rent_sysvar,
  4437. ],
  4438. &[
  4439. Check::success(),
  4440. Check::account(&account_key)
  4441. .data_slice(64, &42u64.to_le_bytes())
  4442. .build(),
  4443. ],
  4444. )
  4445. .unwrap();
  4446. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  4447. assert_eq!(account.amount, 42);
  4448. // initialize native account
  4449. do_process_instruction(
  4450. initialize_account(
  4451. &program_id,
  4452. &account2_key,
  4453. &spl_token::native_mint::id(),
  4454. &owner_key,
  4455. )
  4456. .unwrap(),
  4457. vec![
  4458. &mut account2_account,
  4459. &mut mint_account,
  4460. &mut owner_account,
  4461. &mut rent_sysvar,
  4462. ],
  4463. &[
  4464. Check::success(),
  4465. Check::account(&account2_key)
  4466. .data_slice(109, &[1, 0, 0, 0])
  4467. .build(),
  4468. Check::account(&account2_key)
  4469. .data_slice(64, &42u64.to_le_bytes())
  4470. .build(),
  4471. ],
  4472. )
  4473. .unwrap();
  4474. let account = Account::unpack_unchecked(&account2_account.data).unwrap();
  4475. assert!(account.is_native());
  4476. assert_eq!(account.amount, 42);
  4477. // close non-native account with balance
  4478. assert_eq!(
  4479. Err(TokenError::NonNativeHasBalance.into()),
  4480. do_process_instruction(
  4481. close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
  4482. vec![
  4483. &mut account_account,
  4484. &mut account3_account,
  4485. &mut owner_account,
  4486. ],
  4487. &[
  4488. Check::err(TokenError::NonNativeHasBalance.into()),
  4489. Check::account(&account_key)
  4490. .lamports(account_minimum_balance())
  4491. .build()
  4492. ],
  4493. )
  4494. );
  4495. assert_eq!(account_account.lamports, account_minimum_balance());
  4496. // empty account
  4497. do_process_instruction(
  4498. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 42).unwrap(),
  4499. vec![&mut account_account, &mut mint_account, &mut owner_account],
  4500. &[Check::success()],
  4501. )
  4502. .unwrap();
  4503. // wrong owner
  4504. assert_eq!(
  4505. Err(TokenError::OwnerMismatch.into()),
  4506. do_process_instruction(
  4507. close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
  4508. vec![
  4509. &mut account_account,
  4510. &mut account3_account,
  4511. &mut owner2_account,
  4512. ],
  4513. &[Check::err(TokenError::OwnerMismatch.into())],
  4514. )
  4515. );
  4516. // close account
  4517. do_process_instruction(
  4518. close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
  4519. vec![
  4520. &mut account_account,
  4521. &mut account3_account,
  4522. &mut owner_account,
  4523. ],
  4524. &[
  4525. Check::success(),
  4526. Check::account(&account_key).data(&[]).build(),
  4527. Check::account(&account_key).lamports(0).build(),
  4528. Check::account(&account3_key)
  4529. .lamports(2 * account_minimum_balance())
  4530. .build(),
  4531. ],
  4532. )
  4533. .unwrap();
  4534. assert!(account_account.data.is_empty());
  4535. assert_eq!(account_account.lamports, 0);
  4536. assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
  4537. // fund and initialize new non-native account to test close authority
  4538. let account_key = Pubkey::new_unique();
  4539. let mut account_account = SolanaAccount::new(
  4540. account_minimum_balance(),
  4541. Account::get_packed_len(),
  4542. &program_id,
  4543. );
  4544. let owner2_key = Pubkey::new_unique();
  4545. let mut owner2_account = SolanaAccount::new(
  4546. account_minimum_balance(),
  4547. Account::get_packed_len(),
  4548. &program_id,
  4549. );
  4550. do_process_instruction(
  4551. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  4552. vec![
  4553. &mut account_account,
  4554. &mut mint_account,
  4555. &mut owner_account,
  4556. &mut rent_sysvar,
  4557. ],
  4558. &[Check::success()],
  4559. )
  4560. .unwrap();
  4561. account_account.lamports = 2;
  4562. do_process_instruction(
  4563. set_authority(
  4564. &program_id,
  4565. &account_key,
  4566. Some(&owner2_key),
  4567. AuthorityType::CloseAccount,
  4568. &owner_key,
  4569. &[],
  4570. )
  4571. .unwrap(),
  4572. vec![&mut account_account, &mut owner_account],
  4573. &[Check::success()],
  4574. )
  4575. .unwrap();
  4576. // account owner cannot authorize close if close_authority is set
  4577. assert_eq!(
  4578. Err(TokenError::OwnerMismatch.into()),
  4579. do_process_instruction(
  4580. close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
  4581. vec![
  4582. &mut account_account,
  4583. &mut account3_account,
  4584. &mut owner_account,
  4585. ],
  4586. &[Check::err(TokenError::OwnerMismatch.into())],
  4587. )
  4588. );
  4589. // close non-native account with close_authority
  4590. do_process_instruction(
  4591. close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
  4592. vec![
  4593. &mut account_account,
  4594. &mut account3_account,
  4595. &mut owner2_account,
  4596. ],
  4597. &[
  4598. Check::success(),
  4599. Check::account(&account_key).data(&[]).build(),
  4600. Check::account(&account_key).lamports(0).build(),
  4601. Check::account(&account3_key)
  4602. .lamports(2 * account_minimum_balance() + 2)
  4603. .build(),
  4604. ],
  4605. )
  4606. .unwrap();
  4607. assert!(account_account.data.is_empty());
  4608. assert_eq!(account_account.lamports, 0);
  4609. assert_eq!(account3_account.lamports, 2 * account_minimum_balance() + 2);
  4610. // close native account
  4611. do_process_instruction(
  4612. close_account(&program_id, &account2_key, &account3_key, &owner_key, &[]).unwrap(),
  4613. vec![
  4614. &mut account2_account,
  4615. &mut account3_account,
  4616. &mut owner_account,
  4617. ],
  4618. &[
  4619. Check::success(),
  4620. Check::account(&account2_key).data(&[]).build(),
  4621. Check::account(&account3_key)
  4622. .lamports(3 * account_minimum_balance() + 2 + 42)
  4623. .build(),
  4624. ],
  4625. )
  4626. .unwrap();
  4627. assert!(account2_account.data.is_empty());
  4628. assert_eq!(
  4629. account3_account.lamports,
  4630. 3 * account_minimum_balance() + 2 + 42
  4631. );
  4632. }
  4633. #[test]
  4634. fn test_native_token() {
  4635. let program_id = spl_token::id();
  4636. let mut mint_account =
  4637. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  4638. let account_key = Pubkey::new_unique();
  4639. let mut account_account = SolanaAccount::new(
  4640. account_minimum_balance() + 40,
  4641. Account::get_packed_len(),
  4642. &program_id,
  4643. );
  4644. let account2_key = Pubkey::new_unique();
  4645. let mut account2_account = SolanaAccount::new(
  4646. account_minimum_balance(),
  4647. Account::get_packed_len(),
  4648. &program_id,
  4649. );
  4650. let account3_key = Pubkey::new_unique();
  4651. let mut account3_account = SolanaAccount::new(account_minimum_balance(), 0, &program_id);
  4652. let owner_key = Pubkey::new_unique();
  4653. let mut owner_account = SolanaAccount::default();
  4654. let owner2_key = Pubkey::new_unique();
  4655. let mut owner2_account = SolanaAccount::default();
  4656. let owner3_key = Pubkey::new_unique();
  4657. let mut rent_sysvar = rent_sysvar();
  4658. // initialize native account
  4659. do_process_instruction(
  4660. initialize_account(
  4661. &program_id,
  4662. &account_key,
  4663. &spl_token::native_mint::id(),
  4664. &owner_key,
  4665. )
  4666. .unwrap(),
  4667. vec![
  4668. &mut account_account,
  4669. &mut mint_account,
  4670. &mut owner_account,
  4671. &mut rent_sysvar,
  4672. ],
  4673. &[
  4674. Check::success(),
  4675. Check::account(&account_key)
  4676. .data_slice(109, &[1, 0, 0, 0])
  4677. .build(),
  4678. Check::account(&account_key)
  4679. .data_slice(64, &40u64.to_le_bytes())
  4680. .build(),
  4681. ],
  4682. )
  4683. .unwrap();
  4684. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  4685. assert!(account.is_native());
  4686. assert_eq!(account.amount, 40);
  4687. // initialize native account
  4688. do_process_instruction(
  4689. initialize_account(
  4690. &program_id,
  4691. &account2_key,
  4692. &spl_token::native_mint::id(),
  4693. &owner_key,
  4694. )
  4695. .unwrap(),
  4696. vec![
  4697. &mut account2_account,
  4698. &mut mint_account,
  4699. &mut owner_account,
  4700. &mut rent_sysvar,
  4701. ],
  4702. &[
  4703. Check::success(),
  4704. Check::account(&account2_key)
  4705. .data_slice(109, &[1, 0, 0, 0])
  4706. .build(),
  4707. Check::account(&account2_key)
  4708. .data_slice(64, &0u64.to_le_bytes())
  4709. .build(),
  4710. ],
  4711. )
  4712. .unwrap();
  4713. let account = Account::unpack_unchecked(&account2_account.data).unwrap();
  4714. assert!(account.is_native());
  4715. assert_eq!(account.amount, 0);
  4716. // mint_to unsupported
  4717. assert_eq!(
  4718. Err(TokenError::NativeNotSupported.into()),
  4719. do_process_instruction(
  4720. mint_to(
  4721. &program_id,
  4722. &spl_token::native_mint::id(),
  4723. &account_key,
  4724. &owner_key,
  4725. &[],
  4726. 42
  4727. )
  4728. .unwrap(),
  4729. vec![&mut mint_account, &mut account_account, &mut owner_account],
  4730. &[Check::err(TokenError::NativeNotSupported.into())],
  4731. )
  4732. );
  4733. // burn unsupported
  4734. let bogus_mint_key = Pubkey::new_unique();
  4735. let mut bogus_mint_account =
  4736. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  4737. do_process_instruction(
  4738. initialize_mint(&program_id, &bogus_mint_key, &owner_key, None, 2).unwrap(),
  4739. vec![&mut bogus_mint_account, &mut rent_sysvar],
  4740. &[Check::success()],
  4741. )
  4742. .unwrap();
  4743. assert_eq!(
  4744. Err(TokenError::NativeNotSupported.into()),
  4745. do_process_instruction(
  4746. burn(
  4747. &program_id,
  4748. &account_key,
  4749. &bogus_mint_key,
  4750. &owner_key,
  4751. &[],
  4752. 42
  4753. )
  4754. .unwrap(),
  4755. vec![
  4756. &mut account_account,
  4757. &mut bogus_mint_account,
  4758. &mut owner_account
  4759. ],
  4760. &[Check::err(TokenError::NativeNotSupported.into())],
  4761. )
  4762. );
  4763. // ensure can't transfer below rent-exempt reserve
  4764. assert_eq!(
  4765. Err(TokenError::InsufficientFunds.into()),
  4766. do_process_instruction(
  4767. transfer(
  4768. &program_id,
  4769. &account_key,
  4770. &account2_key,
  4771. &owner_key,
  4772. &[],
  4773. 50,
  4774. )
  4775. .unwrap(),
  4776. vec![
  4777. &mut account_account,
  4778. &mut account2_account,
  4779. &mut owner_account,
  4780. ],
  4781. &[Check::err(TokenError::InsufficientFunds.into())],
  4782. )
  4783. );
  4784. // transfer between native accounts
  4785. do_process_instruction(
  4786. transfer(
  4787. &program_id,
  4788. &account_key,
  4789. &account2_key,
  4790. &owner_key,
  4791. &[],
  4792. 40,
  4793. )
  4794. .unwrap(),
  4795. vec![
  4796. &mut account_account,
  4797. &mut account2_account,
  4798. &mut owner_account,
  4799. ],
  4800. &[
  4801. Check::success(),
  4802. Check::account(&account_key)
  4803. .lamports(account_minimum_balance())
  4804. .build(),
  4805. Check::account(&account_key)
  4806. .data_slice(109, &[1, 0, 0, 0])
  4807. .build(),
  4808. Check::account(&account_key)
  4809. .data_slice(64, &0u64.to_le_bytes())
  4810. .build(),
  4811. Check::account(&account2_key)
  4812. .lamports(account_minimum_balance() + 40)
  4813. .build(),
  4814. Check::account(&account_key)
  4815. .data_slice(109, &[1, 0, 0, 0])
  4816. .build(),
  4817. Check::account(&account2_key)
  4818. .data_slice(64, &40u64.to_le_bytes())
  4819. .build(),
  4820. ],
  4821. )
  4822. .unwrap();
  4823. assert_eq!(account_account.lamports, account_minimum_balance());
  4824. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  4825. assert!(account.is_native());
  4826. assert_eq!(account.amount, 0);
  4827. assert_eq!(account2_account.lamports, account_minimum_balance() + 40);
  4828. let account = Account::unpack_unchecked(&account2_account.data).unwrap();
  4829. assert!(account.is_native());
  4830. assert_eq!(account.amount, 40);
  4831. // set close authority
  4832. do_process_instruction(
  4833. set_authority(
  4834. &program_id,
  4835. &account_key,
  4836. Some(&owner3_key),
  4837. AuthorityType::CloseAccount,
  4838. &owner_key,
  4839. &[],
  4840. )
  4841. .unwrap(),
  4842. vec![&mut account_account, &mut owner_account],
  4843. &[
  4844. Check::success(),
  4845. Check::account(&account_key)
  4846. .data_slice(129, &[1, 0, 0, 0])
  4847. .build(),
  4848. Check::account(&account_key)
  4849. .data_slice(133, owner3_key.as_ref())
  4850. .build(),
  4851. ],
  4852. )
  4853. .unwrap();
  4854. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  4855. assert_eq!(account.close_authority, COption::Some(owner3_key));
  4856. // set new account owner
  4857. do_process_instruction(
  4858. set_authority(
  4859. &program_id,
  4860. &account_key,
  4861. Some(&owner2_key),
  4862. AuthorityType::AccountOwner,
  4863. &owner_key,
  4864. &[],
  4865. )
  4866. .unwrap(),
  4867. vec![&mut account_account, &mut owner_account],
  4868. &[
  4869. Check::success(),
  4870. Check::account(&account_key)
  4871. .data_slice(129, &[0, 0, 0, 0])
  4872. .build(),
  4873. ],
  4874. )
  4875. .unwrap();
  4876. // close authority cleared
  4877. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  4878. assert_eq!(account.close_authority, COption::None);
  4879. // close native account
  4880. do_process_instruction(
  4881. close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
  4882. vec![
  4883. &mut account_account,
  4884. &mut account3_account,
  4885. &mut owner2_account,
  4886. ],
  4887. &[
  4888. Check::success(),
  4889. Check::account(&account_key).lamports(0).build(),
  4890. Check::account(&account3_key)
  4891. .lamports(2 * account_minimum_balance())
  4892. .build(),
  4893. Check::account(&account_key).data(&[]).build(),
  4894. ],
  4895. )
  4896. .unwrap();
  4897. assert_eq!(account_account.lamports, 0);
  4898. assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
  4899. assert!(account_account.data.is_empty());
  4900. }
  4901. #[test]
  4902. fn test_overflow() {
  4903. let program_id = spl_token::id();
  4904. let account_key = Pubkey::new_unique();
  4905. let mut account_account = SolanaAccount::new(
  4906. account_minimum_balance(),
  4907. Account::get_packed_len(),
  4908. &program_id,
  4909. );
  4910. let account2_key = Pubkey::new_unique();
  4911. let mut account2_account = SolanaAccount::new(
  4912. account_minimum_balance(),
  4913. Account::get_packed_len(),
  4914. &program_id,
  4915. );
  4916. let owner_key = Pubkey::new_unique();
  4917. let mut owner_account = SolanaAccount::default();
  4918. let owner2_key = Pubkey::new_unique();
  4919. let mut owner2_account = SolanaAccount::default();
  4920. let mint_owner_key = Pubkey::new_unique();
  4921. let mut mint_owner_account = SolanaAccount::default();
  4922. let mint_key = Pubkey::new_unique();
  4923. let mut mint_account =
  4924. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  4925. let mut rent_sysvar = rent_sysvar();
  4926. // create new mint with owner
  4927. do_process_instruction(
  4928. initialize_mint(&program_id, &mint_key, &mint_owner_key, None, 2).unwrap(),
  4929. vec![&mut mint_account, &mut rent_sysvar],
  4930. &[Check::success()],
  4931. )
  4932. .unwrap();
  4933. // create an account
  4934. do_process_instruction(
  4935. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  4936. vec![
  4937. &mut account_account,
  4938. &mut mint_account,
  4939. &mut owner_account,
  4940. &mut rent_sysvar,
  4941. ],
  4942. &[Check::success()],
  4943. )
  4944. .unwrap();
  4945. // create another account
  4946. do_process_instruction(
  4947. initialize_account(&program_id, &account2_key, &mint_key, &owner2_key).unwrap(),
  4948. vec![
  4949. &mut account2_account,
  4950. &mut mint_account,
  4951. &mut owner2_account,
  4952. &mut rent_sysvar,
  4953. ],
  4954. &[Check::success()],
  4955. )
  4956. .unwrap();
  4957. // mint the max to an account
  4958. do_process_instruction(
  4959. mint_to(
  4960. &program_id,
  4961. &mint_key,
  4962. &account_key,
  4963. &mint_owner_key,
  4964. &[],
  4965. u64::MAX,
  4966. )
  4967. .unwrap(),
  4968. vec![
  4969. &mut mint_account,
  4970. &mut account_account,
  4971. &mut mint_owner_account,
  4972. ],
  4973. &[
  4974. Check::success(),
  4975. Check::account(&account_key)
  4976. .data_slice(64, &u64::MAX.to_le_bytes())
  4977. .build(),
  4978. ],
  4979. )
  4980. .unwrap();
  4981. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  4982. assert_eq!(account.amount, u64::MAX);
  4983. // attempt to mint one more to account
  4984. assert_eq!(
  4985. Err(TokenError::Overflow.into()),
  4986. do_process_instruction(
  4987. mint_to(
  4988. &program_id,
  4989. &mint_key,
  4990. &account_key,
  4991. &mint_owner_key,
  4992. &[],
  4993. 1,
  4994. )
  4995. .unwrap(),
  4996. vec![
  4997. &mut mint_account,
  4998. &mut account_account,
  4999. &mut mint_owner_account,
  5000. ],
  5001. &[
  5002. Check::err(TokenError::Overflow.into()),
  5003. Check::account(&account_key)
  5004. .data_slice(64, &u64::MAX.to_le_bytes())
  5005. .build(),
  5006. ],
  5007. )
  5008. );
  5009. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  5010. assert_eq!(account.amount, u64::MAX);
  5011. // attempt to mint one more to the other account
  5012. assert_eq!(
  5013. Err(TokenError::Overflow.into()),
  5014. do_process_instruction(
  5015. mint_to(
  5016. &program_id,
  5017. &mint_key,
  5018. &account2_key,
  5019. &mint_owner_key,
  5020. &[],
  5021. 1,
  5022. )
  5023. .unwrap(),
  5024. vec![
  5025. &mut mint_account,
  5026. &mut account2_account,
  5027. &mut mint_owner_account,
  5028. ],
  5029. &[Check::err(TokenError::Overflow.into())],
  5030. )
  5031. );
  5032. // burn some of the supply
  5033. do_process_instruction(
  5034. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
  5035. vec![&mut account_account, &mut mint_account, &mut owner_account],
  5036. &[
  5037. Check::success(),
  5038. Check::account(&account_key)
  5039. .data_slice(64, &(u64::MAX - 100).to_le_bytes())
  5040. .build(),
  5041. ],
  5042. )
  5043. .unwrap();
  5044. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  5045. assert_eq!(account.amount, u64::MAX - 100);
  5046. do_process_instruction(
  5047. mint_to(
  5048. &program_id,
  5049. &mint_key,
  5050. &account_key,
  5051. &mint_owner_key,
  5052. &[],
  5053. 100,
  5054. )
  5055. .unwrap(),
  5056. vec![
  5057. &mut mint_account,
  5058. &mut account_account,
  5059. &mut mint_owner_account,
  5060. ],
  5061. &[
  5062. Check::success(),
  5063. Check::account(&account_key)
  5064. .data_slice(64, &u64::MAX.to_le_bytes())
  5065. .build(),
  5066. ],
  5067. )
  5068. .unwrap();
  5069. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  5070. assert_eq!(account.amount, u64::MAX);
  5071. // manipulate account balance to attempt overflow transfer
  5072. let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
  5073. account.amount = 1;
  5074. Account::pack(account, &mut account2_account.data).unwrap();
  5075. assert_eq!(
  5076. Err(TokenError::Overflow.into()),
  5077. do_process_instruction(
  5078. transfer(
  5079. &program_id,
  5080. &account2_key,
  5081. &account_key,
  5082. &owner2_key,
  5083. &[],
  5084. 1,
  5085. )
  5086. .unwrap(),
  5087. vec![
  5088. &mut account2_account,
  5089. &mut account_account,
  5090. &mut owner2_account,
  5091. ],
  5092. &[Check::err(TokenError::Overflow.into())],
  5093. )
  5094. );
  5095. }
  5096. #[test]
  5097. fn test_frozen() {
  5098. let program_id = spl_token::id();
  5099. let account_key = Pubkey::new_unique();
  5100. let mut account_account = SolanaAccount::new(
  5101. account_minimum_balance(),
  5102. Account::get_packed_len(),
  5103. &program_id,
  5104. );
  5105. let account2_key = Pubkey::new_unique();
  5106. let mut account2_account = SolanaAccount::new(
  5107. account_minimum_balance(),
  5108. Account::get_packed_len(),
  5109. &program_id,
  5110. );
  5111. let owner_key = Pubkey::new_unique();
  5112. let mut owner_account = SolanaAccount::default();
  5113. let mint_key = Pubkey::new_unique();
  5114. let mut mint_account =
  5115. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5116. let mut rent_sysvar = rent_sysvar();
  5117. // create new mint and fund first account
  5118. do_process_instruction(
  5119. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5120. vec![&mut mint_account, &mut rent_sysvar],
  5121. &[Check::success()],
  5122. )
  5123. .unwrap();
  5124. // create account
  5125. do_process_instruction(
  5126. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  5127. vec![
  5128. &mut account_account,
  5129. &mut mint_account,
  5130. &mut owner_account,
  5131. &mut rent_sysvar,
  5132. ],
  5133. &[Check::success()],
  5134. )
  5135. .unwrap();
  5136. // create another account
  5137. do_process_instruction(
  5138. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  5139. vec![
  5140. &mut account2_account,
  5141. &mut mint_account,
  5142. &mut owner_account,
  5143. &mut rent_sysvar,
  5144. ],
  5145. &[Check::success()],
  5146. )
  5147. .unwrap();
  5148. // fund first account
  5149. do_process_instruction(
  5150. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  5151. vec![&mut mint_account, &mut account_account, &mut owner_account],
  5152. &[Check::success()],
  5153. )
  5154. .unwrap();
  5155. // no transfer if either account is frozen
  5156. let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
  5157. account.state = AccountState::Frozen;
  5158. Account::pack(account, &mut account2_account.data).unwrap();
  5159. assert_eq!(
  5160. Err(TokenError::AccountFrozen.into()),
  5161. do_process_instruction(
  5162. transfer(
  5163. &program_id,
  5164. &account_key,
  5165. &account2_key,
  5166. &owner_key,
  5167. &[],
  5168. 500,
  5169. )
  5170. .unwrap(),
  5171. vec![
  5172. &mut account_account,
  5173. &mut account2_account,
  5174. &mut owner_account,
  5175. ],
  5176. &[Check::err(TokenError::AccountFrozen.into())],
  5177. )
  5178. );
  5179. let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
  5180. account.state = AccountState::Initialized;
  5181. Account::pack(account, &mut account_account.data).unwrap();
  5182. let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
  5183. account.state = AccountState::Frozen;
  5184. Account::pack(account, &mut account2_account.data).unwrap();
  5185. assert_eq!(
  5186. Err(TokenError::AccountFrozen.into()),
  5187. do_process_instruction(
  5188. transfer(
  5189. &program_id,
  5190. &account_key,
  5191. &account2_key,
  5192. &owner_key,
  5193. &[],
  5194. 500,
  5195. )
  5196. .unwrap(),
  5197. vec![
  5198. &mut account_account,
  5199. &mut account2_account,
  5200. &mut owner_account,
  5201. ],
  5202. &[Check::err(TokenError::AccountFrozen.into())],
  5203. )
  5204. );
  5205. // no approve if account is frozen
  5206. let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
  5207. account.state = AccountState::Frozen;
  5208. Account::pack(account, &mut account_account.data).unwrap();
  5209. let delegate_key = Pubkey::new_unique();
  5210. let mut delegate_account = SolanaAccount::default();
  5211. assert_eq!(
  5212. Err(TokenError::AccountFrozen.into()),
  5213. do_process_instruction(
  5214. approve(
  5215. &program_id,
  5216. &account_key,
  5217. &delegate_key,
  5218. &owner_key,
  5219. &[],
  5220. 100
  5221. )
  5222. .unwrap(),
  5223. vec![
  5224. &mut account_account,
  5225. &mut delegate_account,
  5226. &mut owner_account,
  5227. ],
  5228. &[Check::err(TokenError::AccountFrozen.into())],
  5229. )
  5230. );
  5231. // no revoke if account is frozen
  5232. let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
  5233. account.delegate = COption::Some(delegate_key);
  5234. account.delegated_amount = 100;
  5235. Account::pack(account, &mut account_account.data).unwrap();
  5236. assert_eq!(
  5237. Err(TokenError::AccountFrozen.into()),
  5238. do_process_instruction(
  5239. revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
  5240. vec![&mut account_account, &mut owner_account],
  5241. &[Check::err(TokenError::AccountFrozen.into())],
  5242. )
  5243. );
  5244. // no set authority if account is frozen
  5245. let new_owner_key = Pubkey::new_unique();
  5246. assert_eq!(
  5247. Err(TokenError::AccountFrozen.into()),
  5248. do_process_instruction(
  5249. set_authority(
  5250. &program_id,
  5251. &account_key,
  5252. Some(&new_owner_key),
  5253. AuthorityType::AccountOwner,
  5254. &owner_key,
  5255. &[]
  5256. )
  5257. .unwrap(),
  5258. vec![&mut account_account, &mut owner_account,],
  5259. &[Check::err(TokenError::AccountFrozen.into())],
  5260. )
  5261. );
  5262. // no mint_to if destination account is frozen
  5263. assert_eq!(
  5264. Err(TokenError::AccountFrozen.into()),
  5265. do_process_instruction(
  5266. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 100).unwrap(),
  5267. vec![&mut mint_account, &mut account_account, &mut owner_account,],
  5268. &[Check::err(TokenError::AccountFrozen.into())],
  5269. )
  5270. );
  5271. // no burn if account is frozen
  5272. assert_eq!(
  5273. Err(TokenError::AccountFrozen.into()),
  5274. do_process_instruction(
  5275. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
  5276. vec![&mut account_account, &mut mint_account, &mut owner_account],
  5277. &[Check::err(TokenError::AccountFrozen.into())],
  5278. )
  5279. );
  5280. }
  5281. #[test]
  5282. fn test_freeze_thaw_dups() {
  5283. let program_id = spl_token::id();
  5284. let account1_key = Pubkey::new_unique();
  5285. let mut account1_account = SolanaAccount::new(
  5286. account_minimum_balance(),
  5287. Account::get_packed_len(),
  5288. &program_id,
  5289. );
  5290. let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
  5291. let owner_key = Pubkey::new_unique();
  5292. let mint_key = Pubkey::new_unique();
  5293. let mut mint_account =
  5294. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5295. let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
  5296. let rent_key = rent::id();
  5297. let mut rent_sysvar = rent_sysvar();
  5298. let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
  5299. // create mint
  5300. do_process_instruction_dups(
  5301. initialize_mint(&program_id, &mint_key, &owner_key, Some(&account1_key), 2).unwrap(),
  5302. vec![mint_info.clone(), rent_info.clone()],
  5303. &[Check::success()],
  5304. )
  5305. .unwrap();
  5306. // create account
  5307. do_process_instruction_dups(
  5308. initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
  5309. vec![
  5310. account1_info.clone(),
  5311. mint_info.clone(),
  5312. account1_info.clone(),
  5313. rent_info.clone(),
  5314. ],
  5315. &[Check::success()],
  5316. )
  5317. .unwrap();
  5318. // freeze where mint freeze_authority is account
  5319. do_process_instruction_dups(
  5320. freeze_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
  5321. vec![
  5322. account1_info.clone(),
  5323. mint_info.clone(),
  5324. account1_info.clone(),
  5325. ],
  5326. &[Check::success()],
  5327. )
  5328. .unwrap();
  5329. // thaw where mint freeze_authority is account
  5330. let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
  5331. account.state = AccountState::Frozen;
  5332. Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
  5333. do_process_instruction_dups(
  5334. thaw_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
  5335. vec![
  5336. account1_info.clone(),
  5337. mint_info.clone(),
  5338. account1_info.clone(),
  5339. ],
  5340. &[Check::success()],
  5341. )
  5342. .unwrap();
  5343. }
  5344. #[test]
  5345. fn test_freeze_account() {
  5346. let program_id = spl_token::id();
  5347. let account_key = Pubkey::new_unique();
  5348. let mut account_account = SolanaAccount::new(
  5349. account_minimum_balance(),
  5350. Account::get_packed_len(),
  5351. &program_id,
  5352. );
  5353. let account_owner_key = Pubkey::new_unique();
  5354. let mut account_owner_account = SolanaAccount::default();
  5355. let owner_key = Pubkey::new_unique();
  5356. let mut owner_account = SolanaAccount::default();
  5357. let owner2_key = Pubkey::new_unique();
  5358. let mut owner2_account = SolanaAccount::default();
  5359. let mint_key = Pubkey::new_unique();
  5360. let mut mint_account =
  5361. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5362. let mut rent_sysvar = rent_sysvar();
  5363. // create new mint with owner different from account owner
  5364. do_process_instruction(
  5365. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5366. vec![&mut mint_account, &mut rent_sysvar],
  5367. &[Check::success()],
  5368. )
  5369. .unwrap();
  5370. // create account
  5371. do_process_instruction(
  5372. initialize_account(&program_id, &account_key, &mint_key, &account_owner_key).unwrap(),
  5373. vec![
  5374. &mut account_account,
  5375. &mut mint_account,
  5376. &mut account_owner_account,
  5377. &mut rent_sysvar,
  5378. ],
  5379. &[Check::success()],
  5380. )
  5381. .unwrap();
  5382. // mint to account
  5383. do_process_instruction(
  5384. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  5385. vec![&mut mint_account, &mut account_account, &mut owner_account],
  5386. &[Check::success()],
  5387. )
  5388. .unwrap();
  5389. // mint cannot freeze
  5390. assert_eq!(
  5391. Err(TokenError::MintCannotFreeze.into()),
  5392. do_process_instruction(
  5393. freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  5394. vec![&mut account_account, &mut mint_account, &mut owner_account],
  5395. &[Check::err(TokenError::MintCannotFreeze.into())],
  5396. )
  5397. );
  5398. // missing freeze_authority
  5399. let mut mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
  5400. mint.freeze_authority = COption::Some(owner_key);
  5401. Mint::pack(mint, &mut mint_account.data).unwrap();
  5402. assert_eq!(
  5403. Err(TokenError::OwnerMismatch.into()),
  5404. do_process_instruction(
  5405. freeze_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
  5406. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  5407. &[Check::err(TokenError::OwnerMismatch.into())],
  5408. )
  5409. );
  5410. // check explicit thaw
  5411. assert_eq!(
  5412. Err(TokenError::InvalidState.into()),
  5413. do_process_instruction(
  5414. thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
  5415. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  5416. &[Check::err(TokenError::InvalidState.into())],
  5417. )
  5418. );
  5419. // freeze
  5420. do_process_instruction(
  5421. freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  5422. vec![&mut account_account, &mut mint_account, &mut owner_account],
  5423. &[
  5424. Check::success(),
  5425. Check::account(&account_key)
  5426. .data_slice(108, &[AccountState::Frozen as u8])
  5427. .build(),
  5428. ],
  5429. )
  5430. .unwrap();
  5431. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  5432. assert_eq!(account.state, AccountState::Frozen);
  5433. // check explicit freeze
  5434. assert_eq!(
  5435. Err(TokenError::InvalidState.into()),
  5436. do_process_instruction(
  5437. freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  5438. vec![&mut account_account, &mut mint_account, &mut owner_account],
  5439. &[Check::err(TokenError::InvalidState.into())],
  5440. )
  5441. );
  5442. // check thaw authority
  5443. assert_eq!(
  5444. Err(TokenError::OwnerMismatch.into()),
  5445. do_process_instruction(
  5446. thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
  5447. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  5448. &[Check::err(TokenError::OwnerMismatch.into())],
  5449. )
  5450. );
  5451. // thaw
  5452. do_process_instruction(
  5453. thaw_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  5454. vec![&mut account_account, &mut mint_account, &mut owner_account],
  5455. &[
  5456. Check::success(),
  5457. Check::account(&account_key)
  5458. .data_slice(108, &[AccountState::Initialized as u8])
  5459. .build(),
  5460. ],
  5461. )
  5462. .unwrap();
  5463. let account = Account::unpack_unchecked(&account_account.data).unwrap();
  5464. assert_eq!(account.state, AccountState::Initialized);
  5465. }
  5466. #[test]
  5467. fn test_initialize_account2_and_3() {
  5468. let program_id = spl_token::id();
  5469. let account_key = Pubkey::new_unique();
  5470. let mut account_account = SolanaAccount::new(
  5471. account_minimum_balance(),
  5472. Account::get_packed_len(),
  5473. &program_id,
  5474. );
  5475. let mut account2_account = SolanaAccount::new(
  5476. account_minimum_balance(),
  5477. Account::get_packed_len(),
  5478. &program_id,
  5479. );
  5480. let mut account3_account = SolanaAccount::new(
  5481. account_minimum_balance(),
  5482. Account::get_packed_len(),
  5483. &program_id,
  5484. );
  5485. let owner_key = Pubkey::new_unique();
  5486. let mut owner_account = SolanaAccount::default();
  5487. let mint_key = Pubkey::new_unique();
  5488. let mut mint_account =
  5489. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5490. let mut rent_sysvar = rent_sysvar();
  5491. // create mint
  5492. do_process_instruction(
  5493. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5494. vec![&mut mint_account, &mut rent_sysvar],
  5495. &[Check::success()],
  5496. )
  5497. .unwrap();
  5498. do_process_instruction(
  5499. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  5500. vec![
  5501. &mut account_account,
  5502. &mut mint_account,
  5503. &mut owner_account,
  5504. &mut rent_sysvar,
  5505. ],
  5506. &[Check::success()],
  5507. )
  5508. .unwrap();
  5509. do_process_instruction(
  5510. initialize_account2(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  5511. vec![&mut account2_account, &mut mint_account, &mut rent_sysvar],
  5512. &[Check::success()],
  5513. )
  5514. .unwrap();
  5515. assert_eq!(account_account, account2_account);
  5516. do_process_instruction(
  5517. initialize_account3(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  5518. vec![&mut account3_account, &mut mint_account],
  5519. &[Check::success()],
  5520. )
  5521. .unwrap();
  5522. assert_eq!(account_account, account3_account);
  5523. }
  5524. #[test]
  5525. fn test_sync_native() {
  5526. let program_id = spl_token::id();
  5527. let mint_key = Pubkey::new_unique();
  5528. let mut mint_account =
  5529. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5530. let native_account_key = Pubkey::new_unique();
  5531. let lamports = 40;
  5532. let mut native_account = SolanaAccount::new(
  5533. account_minimum_balance() + lamports,
  5534. Account::get_packed_len(),
  5535. &program_id,
  5536. );
  5537. let non_native_account_key = Pubkey::new_unique();
  5538. let mut non_native_account = SolanaAccount::new(
  5539. account_minimum_balance() + 50,
  5540. Account::get_packed_len(),
  5541. &program_id,
  5542. );
  5543. let owner_key = Pubkey::new_unique();
  5544. let mut owner_account = SolanaAccount::default();
  5545. let mut rent_sysvar = rent_sysvar();
  5546. // initialize non-native mint
  5547. do_process_instruction(
  5548. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5549. vec![&mut mint_account, &mut rent_sysvar],
  5550. &[Check::success()],
  5551. )
  5552. .unwrap();
  5553. // initialize non-native account
  5554. do_process_instruction(
  5555. initialize_account(&program_id, &non_native_account_key, &mint_key, &owner_key).unwrap(),
  5556. vec![
  5557. &mut non_native_account,
  5558. &mut mint_account,
  5559. &mut owner_account,
  5560. &mut rent_sysvar,
  5561. ],
  5562. &[
  5563. Check::success(),
  5564. Check::account(&non_native_account_key)
  5565. .data_slice(109, &[0, 0, 0, 0])
  5566. .build(),
  5567. Check::account(&non_native_account_key)
  5568. .data_slice(64, &0u64.to_le_bytes())
  5569. .build(),
  5570. ],
  5571. )
  5572. .unwrap();
  5573. let account = Account::unpack_unchecked(&non_native_account.data).unwrap();
  5574. assert!(!account.is_native());
  5575. assert_eq!(account.amount, 0);
  5576. // fail sync non-native
  5577. assert_eq!(
  5578. Err(TokenError::NonNativeNotSupported.into()),
  5579. do_process_instruction(
  5580. sync_native(&program_id, &non_native_account_key,).unwrap(),
  5581. vec![&mut non_native_account],
  5582. &[Check::err(TokenError::NonNativeNotSupported.into())],
  5583. )
  5584. );
  5585. // fail sync uninitialized
  5586. assert_eq!(
  5587. Err(ProgramError::UninitializedAccount),
  5588. do_process_instruction(
  5589. sync_native(&program_id, &native_account_key,).unwrap(),
  5590. vec![&mut native_account],
  5591. &[Check::err(ProgramError::UninitializedAccount)],
  5592. )
  5593. );
  5594. // wrap native account
  5595. do_process_instruction(
  5596. initialize_account(
  5597. &program_id,
  5598. &native_account_key,
  5599. &spl_token::native_mint::id(),
  5600. &owner_key,
  5601. )
  5602. .unwrap(),
  5603. vec![
  5604. &mut native_account,
  5605. &mut mint_account,
  5606. &mut owner_account,
  5607. &mut rent_sysvar,
  5608. ],
  5609. &[Check::success()],
  5610. )
  5611. .unwrap();
  5612. // fail sync, not owned by program
  5613. let not_program_id = Pubkey::new_unique();
  5614. native_account.owner = not_program_id;
  5615. assert_eq!(
  5616. Err(ProgramError::IncorrectProgramId),
  5617. do_process_instruction(
  5618. sync_native(&program_id, &native_account_key,).unwrap(),
  5619. vec![&mut native_account],
  5620. &[
  5621. Check::err(ProgramError::IncorrectProgramId),
  5622. Check::account(&native_account_key)
  5623. .data_slice(109, &[1, 0, 0, 0])
  5624. .build(),
  5625. Check::account(&native_account_key)
  5626. .data_slice(64, &lamports.to_le_bytes())
  5627. .build()
  5628. ],
  5629. )
  5630. );
  5631. native_account.owner = program_id;
  5632. let account = Account::unpack_unchecked(&native_account.data).unwrap();
  5633. assert!(account.is_native());
  5634. assert_eq!(account.amount, lamports);
  5635. // sync, no change
  5636. do_process_instruction(
  5637. sync_native(&program_id, &native_account_key).unwrap(),
  5638. vec![&mut native_account],
  5639. &[
  5640. Check::success(),
  5641. Check::account(&native_account_key)
  5642. .data_slice(64, &lamports.to_le_bytes())
  5643. .build(),
  5644. ],
  5645. )
  5646. .unwrap();
  5647. let account = Account::unpack_unchecked(&native_account.data).unwrap();
  5648. assert_eq!(account.amount, lamports);
  5649. // transfer sol
  5650. let new_lamports = lamports + 50;
  5651. native_account.lamports = account_minimum_balance() + new_lamports;
  5652. // success sync
  5653. do_process_instruction(
  5654. sync_native(&program_id, &native_account_key).unwrap(),
  5655. vec![&mut native_account],
  5656. &[
  5657. Check::success(),
  5658. Check::account(&native_account_key)
  5659. .data_slice(64, &new_lamports.to_le_bytes())
  5660. .build(),
  5661. ],
  5662. )
  5663. .unwrap();
  5664. let account = Account::unpack_unchecked(&native_account.data).unwrap();
  5665. assert_eq!(account.amount, new_lamports);
  5666. // reduce sol
  5667. native_account.lamports -= 1;
  5668. // fail sync
  5669. assert_eq!(
  5670. Err(TokenError::InvalidState.into()),
  5671. do_process_instruction(
  5672. sync_native(&program_id, &native_account_key,).unwrap(),
  5673. vec![&mut native_account],
  5674. &[Check::err(TokenError::InvalidState.into())],
  5675. )
  5676. );
  5677. }
  5678. #[test]
  5679. #[serial]
  5680. fn test_get_account_data_size() {
  5681. // see integration tests for return-data validity
  5682. let program_id = spl_token::id();
  5683. let owner_key = Pubkey::new_unique();
  5684. let mut rent_sysvar = rent_sysvar();
  5685. let mut mint_account =
  5686. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5687. let mint_key = Pubkey::new_unique();
  5688. // fail if an invalid mint is passed in
  5689. assert_eq!(
  5690. Err(TokenError::InvalidMint.into()),
  5691. do_process_instruction(
  5692. get_account_data_size(&program_id, &mint_key).unwrap(),
  5693. vec![&mut mint_account],
  5694. &[Check::err(TokenError::InvalidMint.into())],
  5695. )
  5696. );
  5697. do_process_instruction(
  5698. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5699. vec![&mut mint_account, &mut rent_sysvar],
  5700. &[Check::success()],
  5701. )
  5702. .unwrap();
  5703. do_process_instruction(
  5704. get_account_data_size(&program_id, &mint_key).unwrap(),
  5705. vec![&mut mint_account],
  5706. &[
  5707. Check::success(),
  5708. Check::return_data(&Account::LEN.to_le_bytes()),
  5709. ],
  5710. )
  5711. .unwrap();
  5712. }
  5713. #[test]
  5714. fn test_initialize_immutable_owner() {
  5715. let program_id = spl_token::id();
  5716. let account_key = Pubkey::new_unique();
  5717. let mut account_account = SolanaAccount::new(
  5718. account_minimum_balance(),
  5719. Account::get_packed_len(),
  5720. &program_id,
  5721. );
  5722. let owner_key = Pubkey::new_unique();
  5723. let mut owner_account = SolanaAccount::default();
  5724. let mint_key = Pubkey::new_unique();
  5725. let mut mint_account =
  5726. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5727. let mut rent_sysvar = rent_sysvar();
  5728. // create mint
  5729. do_process_instruction(
  5730. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5731. vec![&mut mint_account, &mut rent_sysvar],
  5732. &[Check::success()],
  5733. )
  5734. .unwrap();
  5735. // success initialize immutable
  5736. do_process_instruction(
  5737. initialize_immutable_owner(&program_id, &account_key).unwrap(),
  5738. vec![&mut account_account],
  5739. &[Check::success()],
  5740. )
  5741. .unwrap();
  5742. // create account
  5743. do_process_instruction(
  5744. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  5745. vec![
  5746. &mut account_account,
  5747. &mut mint_account,
  5748. &mut owner_account,
  5749. &mut rent_sysvar,
  5750. ],
  5751. &[Check::success()],
  5752. )
  5753. .unwrap();
  5754. // fail post-init
  5755. assert_eq!(
  5756. Err(TokenError::AlreadyInUse.into()),
  5757. do_process_instruction(
  5758. initialize_immutable_owner(&program_id, &account_key).unwrap(),
  5759. vec![&mut account_account],
  5760. &[Check::err(TokenError::AlreadyInUse.into())],
  5761. )
  5762. );
  5763. }
  5764. #[test]
  5765. #[serial]
  5766. fn test_amount_to_ui_amount() {
  5767. let program_id = spl_token::id();
  5768. let owner_key = Pubkey::new_unique();
  5769. let mint_key = Pubkey::new_unique();
  5770. let mut mint_account =
  5771. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5772. let mut rent_sysvar = rent_sysvar();
  5773. // fail if an invalid mint is passed in
  5774. assert_eq!(
  5775. Err(TokenError::InvalidMint.into()),
  5776. do_process_instruction(
  5777. amount_to_ui_amount(&program_id, &mint_key, 110).unwrap(),
  5778. vec![&mut mint_account],
  5779. &[Check::err(TokenError::InvalidMint.into())],
  5780. )
  5781. );
  5782. // create mint
  5783. do_process_instruction(
  5784. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5785. vec![&mut mint_account, &mut rent_sysvar],
  5786. &[Check::success()],
  5787. )
  5788. .unwrap();
  5789. do_process_instruction(
  5790. amount_to_ui_amount(&program_id, &mint_key, 23).unwrap(),
  5791. vec![&mut mint_account],
  5792. &[Check::success(), Check::return_data("0.23".as_bytes())],
  5793. )
  5794. .unwrap();
  5795. do_process_instruction(
  5796. amount_to_ui_amount(&program_id, &mint_key, 110).unwrap(),
  5797. vec![&mut mint_account],
  5798. &[Check::success(), Check::return_data("1.1".as_bytes())],
  5799. )
  5800. .unwrap();
  5801. do_process_instruction(
  5802. amount_to_ui_amount(&program_id, &mint_key, 4200).unwrap(),
  5803. vec![&mut mint_account],
  5804. &[Check::success(), Check::return_data("42".as_bytes())],
  5805. )
  5806. .unwrap();
  5807. do_process_instruction(
  5808. amount_to_ui_amount(&program_id, &mint_key, 0).unwrap(),
  5809. vec![&mut mint_account],
  5810. &[Check::success(), Check::return_data("0".as_bytes())],
  5811. )
  5812. .unwrap();
  5813. }
  5814. #[test]
  5815. #[serial]
  5816. fn test_ui_amount_to_amount() {
  5817. let program_id = spl_token::id();
  5818. let owner_key = Pubkey::new_unique();
  5819. let mint_key = Pubkey::new_unique();
  5820. let mut mint_account =
  5821. SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
  5822. let mut rent_sysvar = rent_sysvar();
  5823. // fail if an invalid mint is passed in
  5824. assert_eq!(
  5825. Err(TokenError::InvalidMint.into()),
  5826. do_process_instruction(
  5827. ui_amount_to_amount(&program_id, &mint_key, "1.1").unwrap(),
  5828. vec![&mut mint_account],
  5829. &[Check::err(TokenError::InvalidMint.into())],
  5830. )
  5831. );
  5832. // create mint
  5833. do_process_instruction(
  5834. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  5835. vec![&mut mint_account, &mut rent_sysvar],
  5836. &[Check::success()],
  5837. )
  5838. .unwrap();
  5839. do_process_instruction(
  5840. ui_amount_to_amount(&program_id, &mint_key, "0.23").unwrap(),
  5841. vec![&mut mint_account],
  5842. &[Check::success(), Check::return_data(&23u64.to_le_bytes())],
  5843. )
  5844. .unwrap();
  5845. do_process_instruction(
  5846. ui_amount_to_amount(&program_id, &mint_key, "0.20").unwrap(),
  5847. vec![&mut mint_account],
  5848. &[Check::success(), Check::return_data(&20u64.to_le_bytes())],
  5849. )
  5850. .unwrap();
  5851. do_process_instruction(
  5852. ui_amount_to_amount(&program_id, &mint_key, "0.2000").unwrap(),
  5853. vec![&mut mint_account],
  5854. &[Check::success(), Check::return_data(&20u64.to_le_bytes())],
  5855. )
  5856. .unwrap();
  5857. do_process_instruction(
  5858. ui_amount_to_amount(&program_id, &mint_key, ".20").unwrap(),
  5859. vec![&mut mint_account],
  5860. &[Check::success(), Check::return_data(&20u64.to_le_bytes())],
  5861. )
  5862. .unwrap();
  5863. do_process_instruction(
  5864. ui_amount_to_amount(&program_id, &mint_key, "1.1").unwrap(),
  5865. vec![&mut mint_account],
  5866. &[Check::success(), Check::return_data(&110u64.to_le_bytes())],
  5867. )
  5868. .unwrap();
  5869. do_process_instruction(
  5870. ui_amount_to_amount(&program_id, &mint_key, "1.10").unwrap(),
  5871. vec![&mut mint_account],
  5872. &[Check::success(), Check::return_data(&110u64.to_le_bytes())],
  5873. )
  5874. .unwrap();
  5875. do_process_instruction(
  5876. ui_amount_to_amount(&program_id, &mint_key, "42").unwrap(),
  5877. vec![&mut mint_account],
  5878. &[Check::success(), Check::return_data(&4200u64.to_le_bytes())],
  5879. )
  5880. .unwrap();
  5881. do_process_instruction(
  5882. ui_amount_to_amount(&program_id, &mint_key, "42.").unwrap(),
  5883. vec![&mut mint_account],
  5884. &[Check::success(), Check::return_data(&4200u64.to_le_bytes())],
  5885. )
  5886. .unwrap();
  5887. do_process_instruction(
  5888. ui_amount_to_amount(&program_id, &mint_key, "0").unwrap(),
  5889. vec![&mut mint_account],
  5890. &[Check::success(), Check::return_data(&0u64.to_le_bytes())],
  5891. )
  5892. .unwrap();
  5893. // fail if invalid ui_amount passed in
  5894. assert_eq!(
  5895. Err(ProgramError::InvalidArgument),
  5896. do_process_instruction(
  5897. ui_amount_to_amount(&program_id, &mint_key, "").unwrap(),
  5898. vec![&mut mint_account],
  5899. &[Check::err(ProgramError::InvalidArgument)],
  5900. )
  5901. );
  5902. assert_eq!(
  5903. Err(ProgramError::InvalidArgument),
  5904. do_process_instruction(
  5905. ui_amount_to_amount(&program_id, &mint_key, ".").unwrap(),
  5906. vec![&mut mint_account],
  5907. &[Check::err(ProgramError::InvalidArgument)],
  5908. )
  5909. );
  5910. assert_eq!(
  5911. Err(ProgramError::InvalidArgument),
  5912. do_process_instruction(
  5913. ui_amount_to_amount(&program_id, &mint_key, "0.111").unwrap(),
  5914. vec![&mut mint_account],
  5915. &[Check::err(ProgramError::InvalidArgument)],
  5916. )
  5917. );
  5918. assert_eq!(
  5919. Err(ProgramError::InvalidArgument),
  5920. do_process_instruction(
  5921. ui_amount_to_amount(&program_id, &mint_key, "0.t").unwrap(),
  5922. vec![&mut mint_account],
  5923. &[Check::err(ProgramError::InvalidArgument)],
  5924. )
  5925. );
  5926. }