processor.rs 119 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534
  1. //! Program state processor
  2. #![cfg(feature = "program")]
  3. use crate::{
  4. error::TokenError,
  5. instruction::{is_valid_signer_index, AuthorityType, TokenInstruction},
  6. option::COption,
  7. state::{self, Account, AccountState, IsInitialized, Mint, Multisig},
  8. };
  9. use num_traits::FromPrimitive;
  10. use solana_sdk::{
  11. account_info::{next_account_info, AccountInfo},
  12. decode_error::DecodeError,
  13. entrypoint::ProgramResult,
  14. info,
  15. program_error::{PrintProgramError, ProgramError},
  16. pubkey::Pubkey,
  17. sysvar::{rent::Rent, Sysvar},
  18. };
  19. use std::mem::size_of;
  20. /// Program state handler.
  21. pub struct Processor {}
  22. impl Processor {
  23. /// Processes an [InitializeMint](enum.TokenInstruction.html) instruction.
  24. pub fn process_initialize_mint(
  25. accounts: &[AccountInfo],
  26. decimals: u8,
  27. mint_authority: Pubkey,
  28. freeze_authority: COption<Pubkey>,
  29. ) -> ProgramResult {
  30. let account_info_iter = &mut accounts.iter();
  31. let mint_info = next_account_info(account_info_iter)?;
  32. let mint_info_data_len = mint_info.data_len();
  33. let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?;
  34. let mut mint_info_data = mint_info.data.borrow_mut();
  35. let mut mint: &mut Mint = state::unpack_unchecked(&mut mint_info_data)?;
  36. if mint.is_initialized {
  37. return Err(TokenError::AlreadyInUse.into());
  38. }
  39. if !rent.is_exempt(mint_info.lamports(), mint_info_data_len) {
  40. return Err(TokenError::NotRentExempt.into());
  41. }
  42. mint.mint_authority = COption::Some(mint_authority);
  43. mint.decimals = decimals;
  44. mint.is_initialized = true;
  45. mint.freeze_authority = freeze_authority;
  46. Ok(())
  47. }
  48. /// Processes an [InitializeAccount](enum.TokenInstruction.html) instruction.
  49. pub fn process_initialize_account(accounts: &[AccountInfo]) -> ProgramResult {
  50. let account_info_iter = &mut accounts.iter();
  51. let new_account_info = next_account_info(account_info_iter)?;
  52. let mint_info = next_account_info(account_info_iter)?;
  53. let owner_info = next_account_info(account_info_iter)?;
  54. let new_account_info_data_len = new_account_info.data_len();
  55. let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?;
  56. let mut new_account_data = new_account_info.data.borrow_mut();
  57. let mut account: &mut Account = state::unpack_unchecked(&mut new_account_data)?;
  58. if account.is_initialized() {
  59. return Err(TokenError::AlreadyInUse.into());
  60. }
  61. if !rent.is_exempt(new_account_info.lamports(), new_account_info_data_len) {
  62. return Err(TokenError::NotRentExempt.into());
  63. }
  64. account.mint = *mint_info.key;
  65. account.owner = *owner_info.key;
  66. account.delegate = COption::None;
  67. account.delegated_amount = 0;
  68. account.state = AccountState::Initialized;
  69. if *mint_info.key == crate::native_mint::id() {
  70. let rent_exempt_reserve = rent.minimum_balance(new_account_info_data_len);
  71. account.is_native = COption::Some(rent_exempt_reserve);
  72. account.amount = new_account_info.lamports() - rent_exempt_reserve;
  73. } else {
  74. account.is_native = COption::None;
  75. account.amount = 0;
  76. };
  77. Ok(())
  78. }
  79. /// Processes a [InitializeMultisig](enum.TokenInstruction.html) instruction.
  80. pub fn process_initialize_multisig(accounts: &[AccountInfo], m: u8) -> ProgramResult {
  81. let account_info_iter = &mut accounts.iter();
  82. let multisig_info = next_account_info(account_info_iter)?;
  83. let multisig_info_data_len = multisig_info.data_len();
  84. let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?;
  85. let mut multisig_account_data = multisig_info.data.borrow_mut();
  86. let mut multisig: &mut Multisig = state::unpack_unchecked(&mut multisig_account_data)?;
  87. if multisig.is_initialized {
  88. return Err(TokenError::AlreadyInUse.into());
  89. }
  90. if !rent.is_exempt(multisig_info.lamports(), multisig_info_data_len) {
  91. return Err(TokenError::NotRentExempt.into());
  92. }
  93. let signer_infos = account_info_iter.as_slice();
  94. multisig.m = m;
  95. multisig.n = signer_infos.len() as u8;
  96. if !is_valid_signer_index(multisig.n as usize) {
  97. return Err(TokenError::InvalidNumberOfProvidedSigners.into());
  98. }
  99. if !is_valid_signer_index(multisig.m as usize) {
  100. return Err(TokenError::InvalidNumberOfRequiredSigners.into());
  101. }
  102. for (i, signer_info) in signer_infos.iter().enumerate() {
  103. multisig.signers[i] = *signer_info.key;
  104. }
  105. multisig.is_initialized = true;
  106. Ok(())
  107. }
  108. /// Processes a [Transfer](enum.TokenInstruction.html) instruction.
  109. pub fn process_transfer(
  110. program_id: &Pubkey,
  111. accounts: &[AccountInfo],
  112. amount: u64,
  113. ) -> ProgramResult {
  114. let account_info_iter = &mut accounts.iter();
  115. let source_account_info = next_account_info(account_info_iter)?;
  116. let dest_account_info = next_account_info(account_info_iter)?;
  117. let authority_info = next_account_info(account_info_iter)?;
  118. if source_account_info.key == dest_account_info.key {
  119. return Ok(());
  120. }
  121. let mut source_data = source_account_info.data.borrow_mut();
  122. let mut source_account: &mut Account = state::unpack(&mut source_data)?;
  123. let mut dest_data = dest_account_info.data.borrow_mut();
  124. let mut dest_account: &mut Account = state::unpack(&mut dest_data)?;
  125. if source_account.amount < amount {
  126. return Err(TokenError::InsufficientFunds.into());
  127. }
  128. if source_account.mint != dest_account.mint {
  129. return Err(TokenError::MintMismatch.into());
  130. }
  131. if source_account.is_frozen() || dest_account.is_frozen() {
  132. return Err(TokenError::AccountFrozen.into());
  133. }
  134. match source_account.delegate {
  135. COption::Some(ref delegate) if authority_info.key == delegate => {
  136. Self::validate_owner(
  137. program_id,
  138. delegate,
  139. authority_info,
  140. account_info_iter.as_slice(),
  141. )?;
  142. if source_account.delegated_amount < amount {
  143. return Err(TokenError::InsufficientFunds.into());
  144. }
  145. source_account.delegated_amount -= amount;
  146. if source_account.delegated_amount == 0 {
  147. source_account.delegate = COption::None;
  148. }
  149. }
  150. _ => Self::validate_owner(
  151. program_id,
  152. &source_account.owner,
  153. authority_info,
  154. account_info_iter.as_slice(),
  155. )?,
  156. };
  157. source_account.amount -= amount;
  158. dest_account.amount = dest_account
  159. .amount
  160. .checked_add(amount)
  161. .ok_or(TokenError::Overflow)?;
  162. if source_account.is_native() {
  163. **source_account_info.lamports.borrow_mut() -= amount;
  164. **dest_account_info.lamports.borrow_mut() += amount;
  165. }
  166. Ok(())
  167. }
  168. /// Processes an [Approve](enum.TokenInstruction.html) instruction.
  169. pub fn process_approve(
  170. program_id: &Pubkey,
  171. accounts: &[AccountInfo],
  172. amount: u64,
  173. ) -> ProgramResult {
  174. let account_info_iter = &mut accounts.iter();
  175. let source_account_info = next_account_info(account_info_iter)?;
  176. let mut source_data = source_account_info.data.borrow_mut();
  177. let mut source_account: &mut Account = state::unpack(&mut source_data)?;
  178. let delegate_info = next_account_info(account_info_iter)?;
  179. let owner_info = next_account_info(account_info_iter)?;
  180. if source_account.is_frozen() {
  181. return Err(TokenError::AccountFrozen.into());
  182. }
  183. Self::validate_owner(
  184. program_id,
  185. &source_account.owner,
  186. owner_info,
  187. account_info_iter.as_slice(),
  188. )?;
  189. source_account.delegate = COption::Some(*delegate_info.key);
  190. source_account.delegated_amount = amount;
  191. Ok(())
  192. }
  193. /// Processes an [Revoke](enum.TokenInstruction.html) instruction.
  194. pub fn process_revoke(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
  195. let account_info_iter = &mut accounts.iter();
  196. let source_account_info = next_account_info(account_info_iter)?;
  197. let mut source_data = source_account_info.data.borrow_mut();
  198. let mut source_account: &mut Account = state::unpack(&mut source_data)?;
  199. let owner_info = next_account_info(account_info_iter)?;
  200. if source_account.is_frozen() {
  201. return Err(TokenError::AccountFrozen.into());
  202. }
  203. Self::validate_owner(
  204. program_id,
  205. &source_account.owner,
  206. owner_info,
  207. account_info_iter.as_slice(),
  208. )?;
  209. source_account.delegate = COption::None;
  210. source_account.delegated_amount = 0;
  211. Ok(())
  212. }
  213. /// Processes a [SetAuthority](enum.TokenInstruction.html) instruction.
  214. pub fn process_set_authority(
  215. program_id: &Pubkey,
  216. accounts: &[AccountInfo],
  217. authority_type: AuthorityType,
  218. new_authority: COption<Pubkey>,
  219. ) -> ProgramResult {
  220. let account_info_iter = &mut accounts.iter();
  221. let account_info = next_account_info(account_info_iter)?;
  222. let authority_info = next_account_info(account_info_iter)?;
  223. if account_info.data_len() == size_of::<Account>() {
  224. let mut account_data = account_info.data.borrow_mut();
  225. let mut account: &mut Account = state::unpack(&mut account_data)?;
  226. if account.is_frozen() {
  227. return Err(TokenError::AccountFrozen.into());
  228. }
  229. match authority_type {
  230. AuthorityType::AccountHolder => {
  231. Self::validate_owner(
  232. program_id,
  233. &account.owner,
  234. authority_info,
  235. account_info_iter.as_slice(),
  236. )?;
  237. if let COption::Some(authority) = new_authority {
  238. account.owner = authority;
  239. } else {
  240. return Err(TokenError::InvalidInstruction.into());
  241. }
  242. }
  243. AuthorityType::CloseAccount => {
  244. let authority = account.close_authority.unwrap_or(account.owner);
  245. Self::validate_owner(
  246. program_id,
  247. &authority,
  248. authority_info,
  249. account_info_iter.as_slice(),
  250. )?;
  251. account.close_authority = new_authority;
  252. }
  253. _ => {
  254. return Err(TokenError::AuthorityTypeNotSupported.into());
  255. }
  256. }
  257. } else if account_info.data_len() == size_of::<Mint>() {
  258. let mut account_data = account_info.data.borrow_mut();
  259. let mut mint: &mut Mint = state::unpack(&mut account_data)?;
  260. match authority_type {
  261. AuthorityType::MintTokens => {
  262. // Once a mint's supply is fixed, it cannot be undone by setting a new
  263. // mint_authority
  264. let mint_authority = mint
  265. .mint_authority
  266. .ok_or(Into::<ProgramError>::into(TokenError::FixedSupply))?;
  267. Self::validate_owner(
  268. program_id,
  269. &mint_authority,
  270. authority_info,
  271. account_info_iter.as_slice(),
  272. )?;
  273. mint.mint_authority = new_authority;
  274. }
  275. AuthorityType::FreezeAccount => {
  276. // Once a mint's freeze authority is disabled, it cannot be re-enabled by
  277. // setting a new freeze_authority
  278. let freeze_authority = mint
  279. .freeze_authority
  280. .ok_or(Into::<ProgramError>::into(TokenError::MintCannotFreeze))?;
  281. Self::validate_owner(
  282. program_id,
  283. &freeze_authority,
  284. authority_info,
  285. account_info_iter.as_slice(),
  286. )?;
  287. mint.freeze_authority = new_authority;
  288. }
  289. _ => {
  290. return Err(TokenError::AuthorityTypeNotSupported.into());
  291. }
  292. }
  293. } else {
  294. return Err(ProgramError::InvalidArgument);
  295. }
  296. Ok(())
  297. }
  298. /// Processes a [MintTo](enum.TokenInstruction.html) instruction.
  299. pub fn process_mint_to(
  300. program_id: &Pubkey,
  301. accounts: &[AccountInfo],
  302. amount: u64,
  303. ) -> ProgramResult {
  304. let account_info_iter = &mut accounts.iter();
  305. let mint_info = next_account_info(account_info_iter)?;
  306. let dest_account_info = next_account_info(account_info_iter)?;
  307. let owner_info = next_account_info(account_info_iter)?;
  308. let mut dest_account_data = dest_account_info.data.borrow_mut();
  309. let mut dest_account: &mut Account = state::unpack(&mut dest_account_data)?;
  310. if dest_account.is_frozen() {
  311. return Err(TokenError::AccountFrozen.into());
  312. }
  313. if dest_account.is_native() {
  314. return Err(TokenError::NativeNotSupported.into());
  315. }
  316. if mint_info.key != &dest_account.mint {
  317. return Err(TokenError::MintMismatch.into());
  318. }
  319. let mut mint_info_data = mint_info.data.borrow_mut();
  320. let mint: &mut Mint = state::unpack(&mut mint_info_data)?;
  321. match mint.mint_authority {
  322. COption::Some(mint_authority) => {
  323. Self::validate_owner(
  324. program_id,
  325. &mint_authority,
  326. owner_info,
  327. account_info_iter.as_slice(),
  328. )?;
  329. }
  330. COption::None => {
  331. return Err(TokenError::FixedSupply.into());
  332. }
  333. }
  334. dest_account.amount = dest_account
  335. .amount
  336. .checked_add(amount)
  337. .ok_or(TokenError::Overflow)?;
  338. mint.supply = mint
  339. .supply
  340. .checked_add(amount)
  341. .ok_or(TokenError::Overflow)?;
  342. Ok(())
  343. }
  344. /// Processes a [Burn](enum.TokenInstruction.html) instruction.
  345. pub fn process_burn(
  346. program_id: &Pubkey,
  347. accounts: &[AccountInfo],
  348. amount: u64,
  349. ) -> ProgramResult {
  350. let account_info_iter = &mut accounts.iter();
  351. let source_account_info = next_account_info(account_info_iter)?;
  352. let mint_info = next_account_info(account_info_iter)?;
  353. let authority_info = next_account_info(account_info_iter)?;
  354. let mut mint_data = mint_info.data.borrow_mut();
  355. let mint: &mut Mint = state::unpack(&mut mint_data)?;
  356. let mut source_data = source_account_info.data.borrow_mut();
  357. let source_account: &mut Account = state::unpack(&mut source_data)?;
  358. if source_account.is_native() {
  359. return Err(TokenError::NativeNotSupported.into());
  360. }
  361. if mint_info.key != &source_account.mint {
  362. return Err(TokenError::MintMismatch.into());
  363. }
  364. if source_account.amount < amount {
  365. return Err(TokenError::InsufficientFunds.into());
  366. }
  367. if source_account.is_frozen() {
  368. return Err(TokenError::AccountFrozen.into());
  369. }
  370. match source_account.delegate {
  371. COption::Some(ref delegate) if authority_info.key == delegate => {
  372. Self::validate_owner(
  373. program_id,
  374. delegate,
  375. authority_info,
  376. account_info_iter.as_slice(),
  377. )?;
  378. if source_account.delegated_amount < amount {
  379. return Err(TokenError::InsufficientFunds.into());
  380. }
  381. source_account.delegated_amount -= amount;
  382. if source_account.delegated_amount == 0 {
  383. source_account.delegate = COption::None;
  384. }
  385. }
  386. _ => Self::validate_owner(
  387. program_id,
  388. &source_account.owner,
  389. authority_info,
  390. account_info_iter.as_slice(),
  391. )?,
  392. }
  393. source_account.amount -= amount;
  394. mint.supply -= amount;
  395. Ok(())
  396. }
  397. /// Processes a [CloseAccount](enum.TokenInstruction.html) instruction.
  398. pub fn process_close_account(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
  399. let account_info_iter = &mut accounts.iter();
  400. let source_account_info = next_account_info(account_info_iter)?;
  401. let dest_account_info = next_account_info(account_info_iter)?;
  402. let authority_info = next_account_info(account_info_iter)?;
  403. let mut source_data = source_account_info.data.borrow_mut();
  404. let source_account: &mut Account = state::unpack(&mut source_data)?;
  405. if !source_account.is_native() && source_account.amount != 0 {
  406. return Err(TokenError::NonNativeHasBalance.into());
  407. }
  408. let authority = source_account
  409. .close_authority
  410. .unwrap_or(source_account.owner);
  411. Self::validate_owner(
  412. program_id,
  413. &authority,
  414. authority_info,
  415. account_info_iter.as_slice(),
  416. )?;
  417. **dest_account_info.lamports.borrow_mut() += source_account_info.lamports();
  418. **source_account_info.lamports.borrow_mut() = 0;
  419. source_account.amount = 0;
  420. Ok(())
  421. }
  422. /// Processes a [FreezeAccount](enum.TokenInstruction.html) or a
  423. /// [ThawAccount](enum.TokenInstruction.html) instruction.
  424. pub fn process_toggle_freeze_account(
  425. program_id: &Pubkey,
  426. accounts: &[AccountInfo],
  427. freeze: bool,
  428. ) -> ProgramResult {
  429. let account_info_iter = &mut accounts.iter();
  430. let source_account_info = next_account_info(account_info_iter)?;
  431. let mint_info = next_account_info(account_info_iter)?;
  432. let authority_info = next_account_info(account_info_iter)?;
  433. let mut source_data = source_account_info.data.borrow_mut();
  434. let source_account: &mut Account = state::unpack(&mut source_data)?;
  435. if source_account.is_native() {
  436. return Err(TokenError::NativeNotSupported.into());
  437. }
  438. if mint_info.key != &source_account.mint {
  439. return Err(TokenError::MintMismatch.into());
  440. }
  441. if freeze && source_account.is_frozen() || !freeze && !source_account.is_frozen() {
  442. return Err(TokenError::InvalidState.into());
  443. }
  444. let mut mint_info_data = mint_info.data.borrow_mut();
  445. let mint: &mut Mint = state::unpack(&mut mint_info_data)?;
  446. match mint.freeze_authority {
  447. COption::Some(authority) => {
  448. Self::validate_owner(
  449. program_id,
  450. &authority,
  451. authority_info,
  452. account_info_iter.as_slice(),
  453. )?;
  454. }
  455. COption::None => {
  456. return Err(TokenError::MintCannotFreeze.into());
  457. }
  458. }
  459. source_account.state = if freeze {
  460. AccountState::Frozen
  461. } else {
  462. AccountState::Initialized
  463. };
  464. Ok(())
  465. }
  466. /// Processes an [Instruction](enum.Instruction.html).
  467. pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {
  468. let instruction = TokenInstruction::unpack(input)?;
  469. match instruction {
  470. TokenInstruction::InitializeMint {
  471. decimals,
  472. mint_authority,
  473. freeze_authority,
  474. } => {
  475. info!("Instruction: InitializeMint");
  476. Self::process_initialize_mint(accounts, decimals, mint_authority, freeze_authority)
  477. }
  478. TokenInstruction::InitializeAccount => {
  479. info!("Instruction: InitializeAccount");
  480. Self::process_initialize_account(accounts)
  481. }
  482. TokenInstruction::InitializeMultisig { m } => {
  483. info!("Instruction: InitializeMultisig");
  484. Self::process_initialize_multisig(accounts, m)
  485. }
  486. TokenInstruction::Transfer { amount } => {
  487. info!("Instruction: Transfer");
  488. Self::process_transfer(program_id, accounts, amount)
  489. }
  490. TokenInstruction::Approve { amount } => {
  491. info!("Instruction: Approve");
  492. Self::process_approve(program_id, accounts, amount)
  493. }
  494. TokenInstruction::Revoke => {
  495. info!("Instruction: Revoke");
  496. Self::process_revoke(program_id, accounts)
  497. }
  498. TokenInstruction::SetAuthority {
  499. authority_type,
  500. new_authority,
  501. } => {
  502. info!("Instruction: SetAuthority");
  503. Self::process_set_authority(program_id, accounts, authority_type, new_authority)
  504. }
  505. TokenInstruction::MintTo { amount } => {
  506. info!("Instruction: MintTo");
  507. Self::process_mint_to(program_id, accounts, amount)
  508. }
  509. TokenInstruction::Burn { amount } => {
  510. info!("Instruction: Burn");
  511. Self::process_burn(program_id, accounts, amount)
  512. }
  513. TokenInstruction::CloseAccount => {
  514. info!("Instruction: CloseAccount");
  515. Self::process_close_account(program_id, accounts)
  516. }
  517. TokenInstruction::FreezeAccount => {
  518. info!("Instruction: FreezeAccount");
  519. Self::process_toggle_freeze_account(program_id, accounts, true)
  520. }
  521. TokenInstruction::ThawAccount => {
  522. info!("Instruction: FreezeAccount");
  523. Self::process_toggle_freeze_account(program_id, accounts, false)
  524. }
  525. }
  526. }
  527. /// Validates owner(s) are present
  528. pub fn validate_owner(
  529. program_id: &Pubkey,
  530. expected_owner: &Pubkey,
  531. owner_account_info: &AccountInfo,
  532. signers: &[AccountInfo],
  533. ) -> ProgramResult {
  534. if expected_owner != owner_account_info.key {
  535. return Err(TokenError::OwnerMismatch.into());
  536. }
  537. if program_id == owner_account_info.owner
  538. && owner_account_info.data_len() == std::mem::size_of::<Multisig>()
  539. {
  540. let mut owner_data = owner_account_info.data.borrow_mut();
  541. let multisig: &mut Multisig = state::unpack(&mut owner_data)?;
  542. let mut num_signers = 0;
  543. for signer in signers.iter() {
  544. if multisig.signers[0..multisig.n as usize].contains(signer.key) {
  545. if !signer.is_signer {
  546. return Err(ProgramError::MissingRequiredSignature);
  547. }
  548. num_signers += 1;
  549. }
  550. }
  551. if num_signers < multisig.m {
  552. return Err(ProgramError::MissingRequiredSignature);
  553. }
  554. } else if !owner_account_info.is_signer {
  555. return Err(ProgramError::MissingRequiredSignature);
  556. }
  557. Ok(())
  558. }
  559. }
  560. impl PrintProgramError for TokenError {
  561. fn print<E>(&self)
  562. where
  563. E: 'static + std::error::Error + DecodeError<E> + PrintProgramError + FromPrimitive,
  564. {
  565. match self {
  566. TokenError::NotRentExempt => {
  567. info!("Error: Lamport balance below rent-exempt threshold")
  568. }
  569. TokenError::InsufficientFunds => info!("Error: insufficient funds"),
  570. TokenError::MintMismatch => info!("Error: Account not associated with this Mint"),
  571. TokenError::OwnerMismatch => info!("Error: owner does not match"),
  572. TokenError::FixedSupply => info!("Error: the total supply of this token is fixed"),
  573. TokenError::AlreadyInUse => info!("Error: account or token already in use"),
  574. TokenError::InvalidNumberOfProvidedSigners => {
  575. info!("Error: Invalid number of provided signers")
  576. }
  577. TokenError::InvalidNumberOfRequiredSigners => {
  578. info!("Error: Invalid number of required signers")
  579. }
  580. TokenError::UninitializedState => info!("Error: State is uninitialized"),
  581. TokenError::NativeNotSupported => {
  582. info!("Error: Instruction does not support native tokens")
  583. }
  584. TokenError::NonNativeHasBalance => {
  585. info!("Error: Non-native account can only be closed if its balance is zero")
  586. }
  587. TokenError::InvalidInstruction => info!("Error: Invalid instruction"),
  588. TokenError::InvalidState => info!("Error: Invalid account state for operation"),
  589. TokenError::Overflow => info!("Error: Operation overflowed"),
  590. TokenError::AuthorityTypeNotSupported => {
  591. info!("Error: Account does not support specified authority type")
  592. }
  593. TokenError::MintCannotFreeze => info!("Error: This token mint cannot freeze accounts"),
  594. TokenError::AccountFrozen => info!("Error: Account is frozen"),
  595. }
  596. }
  597. }
  598. // Pull in syscall stubs when building for non-BPF targets
  599. #[cfg(not(target_arch = "bpf"))]
  600. solana_sdk::program_stubs!();
  601. #[cfg(test)]
  602. mod tests {
  603. use super::*;
  604. use crate::instruction::{
  605. approve, burn, close_account, freeze_account, initialize_account, initialize_mint,
  606. initialize_multisig, mint_to, revoke, set_authority, thaw_account, transfer, MAX_SIGNERS,
  607. };
  608. use solana_sdk::{
  609. account::Account as SolanaAccount, account_info::create_is_signer_account_infos,
  610. clock::Epoch, instruction::Instruction, sysvar::rent,
  611. };
  612. fn pubkey_rand() -> Pubkey {
  613. Pubkey::new(&rand::random::<[u8; 32]>())
  614. }
  615. fn do_process_instruction(
  616. instruction: Instruction,
  617. accounts: Vec<&mut SolanaAccount>,
  618. ) -> ProgramResult {
  619. let mut meta = instruction
  620. .accounts
  621. .iter()
  622. .zip(accounts)
  623. .map(|(account_meta, account)| (&account_meta.pubkey, account_meta.is_signer, account))
  624. .collect::<Vec<_>>();
  625. let account_infos = create_is_signer_account_infos(&mut meta);
  626. Processor::process(&instruction.program_id, &account_infos, &instruction.data)
  627. }
  628. fn return_token_error_as_program_error() -> ProgramError {
  629. TokenError::MintMismatch.into()
  630. }
  631. fn rent_sysvar() -> SolanaAccount {
  632. rent::create_account(42, &Rent::default())
  633. }
  634. fn mint_minimum_balance() -> u64 {
  635. Rent::default().minimum_balance(size_of::<Mint>())
  636. }
  637. fn account_minimum_balance() -> u64 {
  638. Rent::default().minimum_balance(size_of::<Account>())
  639. }
  640. fn multisig_minimum_balance() -> u64 {
  641. Rent::default().minimum_balance(size_of::<Multisig>())
  642. }
  643. #[test]
  644. fn test_print_error() {
  645. let error = return_token_error_as_program_error();
  646. error.print::<TokenError>();
  647. }
  648. #[test]
  649. #[should_panic(expected = "Custom(2)")]
  650. fn test_error_unwrap() {
  651. Err::<(), ProgramError>(return_token_error_as_program_error()).unwrap();
  652. }
  653. #[test]
  654. fn test_unique_account_sizes() {
  655. assert_ne!(size_of::<Mint>(), 0);
  656. assert_ne!(size_of::<Mint>(), size_of::<Account>());
  657. assert_ne!(size_of::<Mint>(), size_of::<Multisig>());
  658. assert_ne!(size_of::<Account>(), 0);
  659. assert_ne!(size_of::<Account>(), size_of::<Multisig>());
  660. assert_ne!(size_of::<Multisig>(), 0);
  661. }
  662. #[test]
  663. fn test_initialize_mint() {
  664. let program_id = pubkey_rand();
  665. let owner_key = pubkey_rand();
  666. let mint_key = pubkey_rand();
  667. let mut mint_account = SolanaAccount::new(42, size_of::<Mint>(), &program_id);
  668. let mint2_key = pubkey_rand();
  669. let mut mint2_account =
  670. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  671. let mut rent_sysvar = rent_sysvar();
  672. // mint is not rent exempt
  673. assert_eq!(
  674. Err(TokenError::NotRentExempt.into()),
  675. do_process_instruction(
  676. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  677. vec![&mut mint_account, &mut rent_sysvar]
  678. )
  679. );
  680. mint_account.lamports = mint_minimum_balance();
  681. // create new mint
  682. do_process_instruction(
  683. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  684. vec![&mut mint_account, &mut rent_sysvar],
  685. )
  686. .unwrap();
  687. // create twice
  688. assert_eq!(
  689. Err(TokenError::AlreadyInUse.into()),
  690. do_process_instruction(
  691. initialize_mint(&program_id, &mint_key, &owner_key, None, 2,).unwrap(),
  692. vec![&mut mint_account, &mut rent_sysvar]
  693. )
  694. );
  695. // create another mint that can freeze
  696. do_process_instruction(
  697. initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
  698. vec![&mut mint2_account, &mut rent_sysvar],
  699. )
  700. .unwrap();
  701. let mint2: &mut Mint = state::unpack(&mut mint2_account.data).unwrap();
  702. assert_eq!(mint2.freeze_authority, COption::Some(owner_key));
  703. }
  704. #[test]
  705. fn test_initialize_mint_account() {
  706. let program_id = pubkey_rand();
  707. let account_key = pubkey_rand();
  708. let mut account_account = SolanaAccount::new(42, size_of::<Account>(), &program_id);
  709. let owner_key = pubkey_rand();
  710. let mut owner_account = SolanaAccount::default();
  711. let mint_key = pubkey_rand();
  712. let mut mint_account = SolanaAccount::new(0, size_of::<Mint>(), &program_id);
  713. let mut rent_sysvar = rent_sysvar();
  714. // account is not rent exempt
  715. assert_eq!(
  716. Err(TokenError::NotRentExempt.into()),
  717. do_process_instruction(
  718. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  719. vec![
  720. &mut account_account,
  721. &mut mint_account,
  722. &mut owner_account,
  723. &mut rent_sysvar
  724. ],
  725. )
  726. );
  727. account_account.lamports = account_minimum_balance();
  728. // create account
  729. do_process_instruction(
  730. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  731. vec![
  732. &mut account_account,
  733. &mut mint_account,
  734. &mut owner_account,
  735. &mut rent_sysvar,
  736. ],
  737. )
  738. .unwrap();
  739. // create twice
  740. assert_eq!(
  741. Err(TokenError::AlreadyInUse.into()),
  742. do_process_instruction(
  743. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  744. vec![
  745. &mut account_account,
  746. &mut mint_account,
  747. &mut owner_account,
  748. &mut rent_sysvar
  749. ],
  750. )
  751. );
  752. }
  753. #[test]
  754. fn test_transfer() {
  755. let program_id = pubkey_rand();
  756. let account_key = pubkey_rand();
  757. let mut account_account =
  758. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  759. let account2_key = pubkey_rand();
  760. let mut account2_account =
  761. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  762. let account3_key = pubkey_rand();
  763. let mut account3_account =
  764. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  765. let delegate_key = pubkey_rand();
  766. let mut delegate_account = SolanaAccount::default();
  767. let mismatch_key = pubkey_rand();
  768. let mut mismatch_account =
  769. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  770. let owner_key = pubkey_rand();
  771. let mut owner_account = SolanaAccount::default();
  772. let owner2_key = pubkey_rand();
  773. let mut owner2_account = SolanaAccount::default();
  774. let mint_key = pubkey_rand();
  775. let mut mint_account =
  776. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  777. let mint2_key = pubkey_rand();
  778. let mut mint2_account =
  779. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  780. let mut rent_sysvar = rent_sysvar();
  781. // create account
  782. do_process_instruction(
  783. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  784. vec![
  785. &mut account_account,
  786. &mut mint_account,
  787. &mut owner_account,
  788. &mut rent_sysvar,
  789. ],
  790. )
  791. .unwrap();
  792. // create another account
  793. do_process_instruction(
  794. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  795. vec![
  796. &mut account2_account,
  797. &mut mint_account,
  798. &mut owner_account,
  799. &mut rent_sysvar,
  800. ],
  801. )
  802. .unwrap();
  803. // create another account
  804. do_process_instruction(
  805. initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
  806. vec![
  807. &mut account3_account,
  808. &mut mint_account,
  809. &mut owner_account,
  810. &mut rent_sysvar,
  811. ],
  812. )
  813. .unwrap();
  814. // create mismatch account
  815. do_process_instruction(
  816. initialize_account(&program_id, &mismatch_key, &mint2_key, &owner_key).unwrap(),
  817. vec![
  818. &mut mismatch_account,
  819. &mut mint2_account,
  820. &mut owner_account,
  821. &mut rent_sysvar,
  822. ],
  823. )
  824. .unwrap();
  825. // create new mint & mint to account
  826. do_process_instruction(
  827. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  828. vec![&mut mint_account, &mut rent_sysvar],
  829. )
  830. .unwrap();
  831. do_process_instruction(
  832. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  833. vec![&mut mint_account, &mut account_account, &mut owner_account],
  834. )
  835. .unwrap();
  836. // missing signer
  837. let mut instruction = transfer(
  838. &program_id,
  839. &account_key,
  840. &account2_key,
  841. &owner_key,
  842. &[],
  843. 1000,
  844. )
  845. .unwrap();
  846. instruction.accounts[2].is_signer = false;
  847. assert_eq!(
  848. Err(ProgramError::MissingRequiredSignature),
  849. do_process_instruction(
  850. instruction,
  851. vec![
  852. &mut account_account,
  853. &mut account2_account,
  854. &mut owner_account,
  855. ],
  856. )
  857. );
  858. // mismatch mint
  859. assert_eq!(
  860. Err(TokenError::MintMismatch.into()),
  861. do_process_instruction(
  862. transfer(
  863. &program_id,
  864. &account_key,
  865. &mismatch_key,
  866. &owner_key,
  867. &[],
  868. 1000
  869. )
  870. .unwrap(),
  871. vec![
  872. &mut account_account,
  873. &mut mismatch_account,
  874. &mut owner_account,
  875. ],
  876. )
  877. );
  878. // missing owner
  879. assert_eq!(
  880. Err(TokenError::OwnerMismatch.into()),
  881. do_process_instruction(
  882. transfer(
  883. &program_id,
  884. &account_key,
  885. &account2_key,
  886. &owner2_key,
  887. &[],
  888. 1000
  889. )
  890. .unwrap(),
  891. vec![
  892. &mut account_account,
  893. &mut account2_account,
  894. &mut owner2_account,
  895. ],
  896. )
  897. );
  898. // transfer
  899. do_process_instruction(
  900. transfer(
  901. &program_id,
  902. &account_key,
  903. &account2_key,
  904. &owner_key,
  905. &[],
  906. 1000,
  907. )
  908. .unwrap(),
  909. vec![
  910. &mut account_account,
  911. &mut account2_account,
  912. &mut owner_account,
  913. ],
  914. )
  915. .unwrap();
  916. // insufficient funds
  917. assert_eq!(
  918. Err(TokenError::InsufficientFunds.into()),
  919. do_process_instruction(
  920. transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 1).unwrap(),
  921. vec![
  922. &mut account_account,
  923. &mut account2_account,
  924. &mut owner_account,
  925. ],
  926. )
  927. );
  928. // transfer half back
  929. do_process_instruction(
  930. transfer(
  931. &program_id,
  932. &account2_key,
  933. &account_key,
  934. &owner_key,
  935. &[],
  936. 500,
  937. )
  938. .unwrap(),
  939. vec![
  940. &mut account2_account,
  941. &mut account_account,
  942. &mut owner_account,
  943. ],
  944. )
  945. .unwrap();
  946. // transfer rest
  947. do_process_instruction(
  948. transfer(
  949. &program_id,
  950. &account2_key,
  951. &account_key,
  952. &owner_key,
  953. &[],
  954. 500,
  955. )
  956. .unwrap(),
  957. vec![
  958. &mut account2_account,
  959. &mut account_account,
  960. &mut owner_account,
  961. ],
  962. )
  963. .unwrap();
  964. // transfer to self
  965. {
  966. let instruction = transfer(
  967. &program_id,
  968. &account_key,
  969. &account_key,
  970. &owner_key,
  971. &[],
  972. 500,
  973. )
  974. .unwrap();
  975. let account_account_info = AccountInfo::from((
  976. &instruction.accounts[0].pubkey,
  977. instruction.accounts[0].is_signer,
  978. &mut account_account,
  979. ));
  980. let owner_account_info = AccountInfo::from((
  981. &instruction.accounts[2].pubkey,
  982. instruction.accounts[2].is_signer,
  983. &mut owner_account,
  984. ));
  985. Processor::process(
  986. &instruction.program_id,
  987. &[
  988. account_account_info.clone(),
  989. account_account_info,
  990. owner_account_info,
  991. ],
  992. &instruction.data,
  993. )
  994. .unwrap()
  995. }
  996. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  997. assert_eq!(account.amount, 1000);
  998. // insufficient funds
  999. assert_eq!(
  1000. Err(TokenError::InsufficientFunds.into()),
  1001. do_process_instruction(
  1002. transfer(&program_id, &account2_key, &account_key, &owner_key, &[], 1).unwrap(),
  1003. vec![
  1004. &mut account2_account,
  1005. &mut account_account,
  1006. &mut owner_account,
  1007. ],
  1008. )
  1009. );
  1010. // approve delegate
  1011. do_process_instruction(
  1012. approve(
  1013. &program_id,
  1014. &account_key,
  1015. &delegate_key,
  1016. &owner_key,
  1017. &[],
  1018. 100,
  1019. )
  1020. .unwrap(),
  1021. vec![
  1022. &mut account_account,
  1023. &mut delegate_account,
  1024. &mut owner_account,
  1025. ],
  1026. )
  1027. .unwrap();
  1028. // transfer via delegate
  1029. do_process_instruction(
  1030. transfer(
  1031. &program_id,
  1032. &account_key,
  1033. &account2_key,
  1034. &delegate_key,
  1035. &[],
  1036. 100,
  1037. )
  1038. .unwrap(),
  1039. vec![
  1040. &mut account_account,
  1041. &mut account2_account,
  1042. &mut delegate_account,
  1043. ],
  1044. )
  1045. .unwrap();
  1046. // insufficient funds approved via delegate
  1047. assert_eq!(
  1048. Err(TokenError::OwnerMismatch.into()),
  1049. do_process_instruction(
  1050. transfer(
  1051. &program_id,
  1052. &account_key,
  1053. &account2_key,
  1054. &delegate_key,
  1055. &[],
  1056. 100
  1057. )
  1058. .unwrap(),
  1059. vec![
  1060. &mut account_account,
  1061. &mut account2_account,
  1062. &mut delegate_account,
  1063. ],
  1064. )
  1065. );
  1066. // transfer rest
  1067. do_process_instruction(
  1068. transfer(
  1069. &program_id,
  1070. &account_key,
  1071. &account2_key,
  1072. &owner_key,
  1073. &[],
  1074. 900,
  1075. )
  1076. .unwrap(),
  1077. vec![
  1078. &mut account_account,
  1079. &mut account2_account,
  1080. &mut owner_account,
  1081. ],
  1082. )
  1083. .unwrap();
  1084. // approve delegate
  1085. do_process_instruction(
  1086. approve(
  1087. &program_id,
  1088. &account_key,
  1089. &delegate_key,
  1090. &owner_key,
  1091. &[],
  1092. 100,
  1093. )
  1094. .unwrap(),
  1095. vec![
  1096. &mut account_account,
  1097. &mut delegate_account,
  1098. &mut owner_account,
  1099. ],
  1100. )
  1101. .unwrap();
  1102. // insufficient funds in source account via delegate
  1103. assert_eq!(
  1104. Err(TokenError::InsufficientFunds.into()),
  1105. do_process_instruction(
  1106. transfer(
  1107. &program_id,
  1108. &account_key,
  1109. &account2_key,
  1110. &delegate_key,
  1111. &[],
  1112. 100
  1113. )
  1114. .unwrap(),
  1115. vec![
  1116. &mut account_account,
  1117. &mut account2_account,
  1118. &mut delegate_account,
  1119. ],
  1120. )
  1121. );
  1122. }
  1123. #[test]
  1124. fn test_mintable_token_with_zero_supply() {
  1125. let program_id = pubkey_rand();
  1126. let account_key = pubkey_rand();
  1127. let mut account_account =
  1128. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1129. let owner_key = pubkey_rand();
  1130. let mut owner_account = SolanaAccount::default();
  1131. let mint_key = pubkey_rand();
  1132. let mut mint_account =
  1133. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1134. let mut rent_sysvar = rent_sysvar();
  1135. // create account
  1136. do_process_instruction(
  1137. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  1138. vec![
  1139. &mut account_account,
  1140. &mut owner_account,
  1141. &mut mint_account,
  1142. &mut rent_sysvar,
  1143. ],
  1144. )
  1145. .unwrap();
  1146. // create mint-able token with zero supply
  1147. let decimals = 2;
  1148. do_process_instruction(
  1149. initialize_mint(&program_id, &mint_key, &owner_key, None, decimals).unwrap(),
  1150. vec![&mut mint_account, &mut rent_sysvar],
  1151. )
  1152. .unwrap();
  1153. let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
  1154. assert_eq!(
  1155. *mint,
  1156. Mint {
  1157. mint_authority: COption::Some(owner_key),
  1158. supply: 0,
  1159. decimals,
  1160. is_initialized: true,
  1161. freeze_authority: COption::None,
  1162. }
  1163. );
  1164. // mint to
  1165. do_process_instruction(
  1166. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
  1167. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1168. )
  1169. .unwrap();
  1170. let _: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
  1171. let dest_account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  1172. assert_eq!(dest_account.amount, 42);
  1173. }
  1174. #[test]
  1175. fn test_approve() {
  1176. let program_id = pubkey_rand();
  1177. let account_key = pubkey_rand();
  1178. let mut account_account =
  1179. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1180. let account2_key = pubkey_rand();
  1181. let mut account2_account =
  1182. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1183. let delegate_key = pubkey_rand();
  1184. let mut delegate_account = SolanaAccount::default();
  1185. let owner_key = pubkey_rand();
  1186. let mut owner_account = SolanaAccount::default();
  1187. let owner2_key = pubkey_rand();
  1188. let mut owner2_account = SolanaAccount::default();
  1189. let mint_key = pubkey_rand();
  1190. let mut mint_account =
  1191. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1192. let mut rent_sysvar = rent_sysvar();
  1193. // create account
  1194. do_process_instruction(
  1195. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  1196. vec![
  1197. &mut account_account,
  1198. &mut owner_account,
  1199. &mut mint_account,
  1200. &mut rent_sysvar,
  1201. ],
  1202. )
  1203. .unwrap();
  1204. // create another account
  1205. do_process_instruction(
  1206. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  1207. vec![
  1208. &mut account2_account,
  1209. &mut owner_account,
  1210. &mut mint_account,
  1211. &mut rent_sysvar,
  1212. ],
  1213. )
  1214. .unwrap();
  1215. // create new mint & mint to account
  1216. do_process_instruction(
  1217. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  1218. vec![&mut mint_account, &mut rent_sysvar],
  1219. )
  1220. .unwrap();
  1221. do_process_instruction(
  1222. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  1223. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1224. )
  1225. .unwrap();
  1226. // missing signer
  1227. let mut instruction = approve(
  1228. &program_id,
  1229. &account_key,
  1230. &delegate_key,
  1231. &owner_key,
  1232. &[],
  1233. 100,
  1234. )
  1235. .unwrap();
  1236. instruction.accounts[2].is_signer = false;
  1237. assert_eq!(
  1238. Err(ProgramError::MissingRequiredSignature),
  1239. do_process_instruction(
  1240. instruction,
  1241. vec![
  1242. &mut account_account,
  1243. &mut delegate_account,
  1244. &mut owner_account,
  1245. ],
  1246. )
  1247. );
  1248. // no owner
  1249. assert_eq!(
  1250. Err(TokenError::OwnerMismatch.into()),
  1251. do_process_instruction(
  1252. approve(
  1253. &program_id,
  1254. &account_key,
  1255. &delegate_key,
  1256. &owner2_key,
  1257. &[],
  1258. 100
  1259. )
  1260. .unwrap(),
  1261. vec![
  1262. &mut account_account,
  1263. &mut delegate_account,
  1264. &mut owner2_account,
  1265. ],
  1266. )
  1267. );
  1268. // approve delegate
  1269. do_process_instruction(
  1270. approve(
  1271. &program_id,
  1272. &account_key,
  1273. &delegate_key,
  1274. &owner_key,
  1275. &[],
  1276. 100,
  1277. )
  1278. .unwrap(),
  1279. vec![
  1280. &mut account_account,
  1281. &mut delegate_account,
  1282. &mut owner_account,
  1283. ],
  1284. )
  1285. .unwrap();
  1286. // revoke delegate
  1287. do_process_instruction(
  1288. revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
  1289. vec![&mut account_account, &mut owner_account],
  1290. )
  1291. .unwrap();
  1292. }
  1293. #[test]
  1294. fn test_set_authority() {
  1295. let program_id = pubkey_rand();
  1296. let account_key = pubkey_rand();
  1297. let mut account_account =
  1298. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1299. let account2_key = pubkey_rand();
  1300. let mut account2_account =
  1301. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1302. let owner_key = pubkey_rand();
  1303. let mut owner_account = SolanaAccount::default();
  1304. let owner2_key = pubkey_rand();
  1305. let mut owner2_account = SolanaAccount::default();
  1306. let owner3_key = pubkey_rand();
  1307. let mint_key = pubkey_rand();
  1308. let mut mint_account =
  1309. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1310. let mint2_key = pubkey_rand();
  1311. let mut mint2_account =
  1312. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1313. let mut rent_sysvar = rent_sysvar();
  1314. // invalid account
  1315. assert_eq!(
  1316. Err(TokenError::UninitializedState.into()),
  1317. do_process_instruction(
  1318. set_authority(
  1319. &program_id,
  1320. &account_key,
  1321. Some(&owner2_key),
  1322. AuthorityType::AccountHolder,
  1323. &owner_key,
  1324. &[]
  1325. )
  1326. .unwrap(),
  1327. vec![&mut account_account, &mut owner_account],
  1328. )
  1329. );
  1330. // create account
  1331. do_process_instruction(
  1332. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  1333. vec![
  1334. &mut account_account,
  1335. &mut mint_account,
  1336. &mut owner_account,
  1337. &mut rent_sysvar,
  1338. ],
  1339. )
  1340. .unwrap();
  1341. // create another account
  1342. do_process_instruction(
  1343. initialize_account(&program_id, &account2_key, &mint2_key, &owner_key).unwrap(),
  1344. vec![
  1345. &mut account2_account,
  1346. &mut mint2_account,
  1347. &mut owner_account,
  1348. &mut rent_sysvar,
  1349. ],
  1350. )
  1351. .unwrap();
  1352. // missing owner
  1353. assert_eq!(
  1354. Err(TokenError::OwnerMismatch.into()),
  1355. do_process_instruction(
  1356. set_authority(
  1357. &program_id,
  1358. &account_key,
  1359. Some(&owner_key),
  1360. AuthorityType::AccountHolder,
  1361. &owner2_key,
  1362. &[]
  1363. )
  1364. .unwrap(),
  1365. vec![&mut account_account, &mut owner2_account],
  1366. )
  1367. );
  1368. // owner did not sign
  1369. let mut instruction = set_authority(
  1370. &program_id,
  1371. &account_key,
  1372. Some(&owner2_key),
  1373. AuthorityType::AccountHolder,
  1374. &owner_key,
  1375. &[],
  1376. )
  1377. .unwrap();
  1378. instruction.accounts[1].is_signer = false;
  1379. assert_eq!(
  1380. Err(ProgramError::MissingRequiredSignature),
  1381. do_process_instruction(instruction, vec![&mut account_account, &mut owner_account,],)
  1382. );
  1383. // wrong authority type
  1384. assert_eq!(
  1385. Err(TokenError::AuthorityTypeNotSupported.into()),
  1386. do_process_instruction(
  1387. set_authority(
  1388. &program_id,
  1389. &account_key,
  1390. Some(&owner2_key),
  1391. AuthorityType::FreezeAccount,
  1392. &owner_key,
  1393. &[],
  1394. )
  1395. .unwrap(),
  1396. vec![&mut account_account, &mut owner_account],
  1397. )
  1398. );
  1399. // account owner may not be set to None
  1400. assert_eq!(
  1401. Err(TokenError::InvalidInstruction.into()),
  1402. do_process_instruction(
  1403. set_authority(
  1404. &program_id,
  1405. &account_key,
  1406. None,
  1407. AuthorityType::AccountHolder,
  1408. &owner_key,
  1409. &[],
  1410. )
  1411. .unwrap(),
  1412. vec![&mut account_account, &mut owner_account],
  1413. )
  1414. );
  1415. // set owner
  1416. do_process_instruction(
  1417. set_authority(
  1418. &program_id,
  1419. &account_key,
  1420. Some(&owner2_key),
  1421. AuthorityType::AccountHolder,
  1422. &owner_key,
  1423. &[],
  1424. )
  1425. .unwrap(),
  1426. vec![&mut account_account, &mut owner_account],
  1427. )
  1428. .unwrap();
  1429. // set close_authority
  1430. do_process_instruction(
  1431. set_authority(
  1432. &program_id,
  1433. &account_key,
  1434. Some(&owner2_key),
  1435. AuthorityType::CloseAccount,
  1436. &owner2_key,
  1437. &[],
  1438. )
  1439. .unwrap(),
  1440. vec![&mut account_account, &mut owner2_account],
  1441. )
  1442. .unwrap();
  1443. // close_authority may be set to None
  1444. do_process_instruction(
  1445. set_authority(
  1446. &program_id,
  1447. &account_key,
  1448. None,
  1449. AuthorityType::CloseAccount,
  1450. &owner2_key,
  1451. &[],
  1452. )
  1453. .unwrap(),
  1454. vec![&mut account_account, &mut owner2_account],
  1455. )
  1456. .unwrap();
  1457. // create new mint with owner
  1458. do_process_instruction(
  1459. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  1460. vec![&mut mint_account, &mut rent_sysvar],
  1461. )
  1462. .unwrap();
  1463. // wrong owner
  1464. assert_eq!(
  1465. Err(TokenError::OwnerMismatch.into()),
  1466. do_process_instruction(
  1467. set_authority(
  1468. &program_id,
  1469. &mint_key,
  1470. Some(&owner3_key),
  1471. AuthorityType::MintTokens,
  1472. &owner2_key,
  1473. &[]
  1474. )
  1475. .unwrap(),
  1476. vec![&mut mint_account, &mut owner2_account],
  1477. )
  1478. );
  1479. // owner did not sign
  1480. let mut instruction = set_authority(
  1481. &program_id,
  1482. &mint_key,
  1483. Some(&owner2_key),
  1484. AuthorityType::MintTokens,
  1485. &owner_key,
  1486. &[],
  1487. )
  1488. .unwrap();
  1489. instruction.accounts[1].is_signer = false;
  1490. assert_eq!(
  1491. Err(ProgramError::MissingRequiredSignature),
  1492. do_process_instruction(instruction, vec![&mut mint_account, &mut owner_account],)
  1493. );
  1494. // cannot freeze
  1495. assert_eq!(
  1496. Err(TokenError::MintCannotFreeze.into()),
  1497. do_process_instruction(
  1498. set_authority(
  1499. &program_id,
  1500. &mint_key,
  1501. Some(&owner2_key),
  1502. AuthorityType::FreezeAccount,
  1503. &owner_key,
  1504. &[],
  1505. )
  1506. .unwrap(),
  1507. vec![&mut mint_account, &mut owner_account],
  1508. )
  1509. );
  1510. // set owner
  1511. do_process_instruction(
  1512. set_authority(
  1513. &program_id,
  1514. &mint_key,
  1515. Some(&owner2_key),
  1516. AuthorityType::MintTokens,
  1517. &owner_key,
  1518. &[],
  1519. )
  1520. .unwrap(),
  1521. vec![&mut mint_account, &mut owner_account],
  1522. )
  1523. .unwrap();
  1524. // set owner to None
  1525. do_process_instruction(
  1526. set_authority(
  1527. &program_id,
  1528. &mint_key,
  1529. None,
  1530. AuthorityType::MintTokens,
  1531. &owner2_key,
  1532. &[],
  1533. )
  1534. .unwrap(),
  1535. vec![&mut mint_account, &mut owner2_account],
  1536. )
  1537. .unwrap();
  1538. // test unsetting mint_authority is one-way operation
  1539. assert_eq!(
  1540. Err(TokenError::FixedSupply.into()),
  1541. do_process_instruction(
  1542. set_authority(
  1543. &program_id,
  1544. &mint2_key,
  1545. Some(&owner2_key),
  1546. AuthorityType::MintTokens,
  1547. &owner_key,
  1548. &[]
  1549. )
  1550. .unwrap(),
  1551. vec![&mut mint_account, &mut owner_account],
  1552. )
  1553. );
  1554. // create mint with owner and freeze_authority
  1555. do_process_instruction(
  1556. initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
  1557. vec![&mut mint2_account, &mut rent_sysvar],
  1558. )
  1559. .unwrap();
  1560. // set freeze_authority
  1561. do_process_instruction(
  1562. set_authority(
  1563. &program_id,
  1564. &mint2_key,
  1565. Some(&owner2_key),
  1566. AuthorityType::FreezeAccount,
  1567. &owner_key,
  1568. &[],
  1569. )
  1570. .unwrap(),
  1571. vec![&mut mint2_account, &mut owner_account],
  1572. )
  1573. .unwrap();
  1574. // test unsetting freeze_authority is one-way operation
  1575. do_process_instruction(
  1576. set_authority(
  1577. &program_id,
  1578. &mint2_key,
  1579. None,
  1580. AuthorityType::FreezeAccount,
  1581. &owner2_key,
  1582. &[],
  1583. )
  1584. .unwrap(),
  1585. vec![&mut mint2_account, &mut owner2_account],
  1586. )
  1587. .unwrap();
  1588. assert_eq!(
  1589. Err(TokenError::MintCannotFreeze.into()),
  1590. do_process_instruction(
  1591. set_authority(
  1592. &program_id,
  1593. &mint2_key,
  1594. Some(&owner2_key),
  1595. AuthorityType::FreezeAccount,
  1596. &owner_key,
  1597. &[],
  1598. )
  1599. .unwrap(),
  1600. vec![&mut mint2_account, &mut owner2_account],
  1601. )
  1602. );
  1603. }
  1604. #[test]
  1605. fn test_mint_to() {
  1606. let program_id = pubkey_rand();
  1607. let account_key = pubkey_rand();
  1608. let mut account_account =
  1609. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1610. let account2_key = pubkey_rand();
  1611. let mut account2_account =
  1612. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1613. let account3_key = pubkey_rand();
  1614. let mut account3_account =
  1615. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1616. let mismatch_key = pubkey_rand();
  1617. let mut mismatch_account =
  1618. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1619. let owner_key = pubkey_rand();
  1620. let mut owner_account = SolanaAccount::default();
  1621. let owner2_key = pubkey_rand();
  1622. let mut owner2_account = SolanaAccount::default();
  1623. let mint_key = pubkey_rand();
  1624. let mut mint_account =
  1625. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1626. let mint2_key = pubkey_rand();
  1627. let mut mint2_account =
  1628. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1629. let uninitialized_key = pubkey_rand();
  1630. let mut uninitialized_account =
  1631. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1632. let mut rent_sysvar = rent_sysvar();
  1633. // create account
  1634. do_process_instruction(
  1635. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  1636. vec![
  1637. &mut account_account,
  1638. &mut mint_account,
  1639. &mut owner_account,
  1640. &mut rent_sysvar,
  1641. ],
  1642. )
  1643. .unwrap();
  1644. // create another account
  1645. do_process_instruction(
  1646. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  1647. vec![
  1648. &mut account2_account,
  1649. &mut mint_account,
  1650. &mut owner_account,
  1651. &mut rent_sysvar,
  1652. ],
  1653. )
  1654. .unwrap();
  1655. // create another account
  1656. do_process_instruction(
  1657. initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
  1658. vec![
  1659. &mut account3_account,
  1660. &mut mint_account,
  1661. &mut owner_account,
  1662. &mut rent_sysvar,
  1663. ],
  1664. )
  1665. .unwrap();
  1666. // create mismatch account
  1667. do_process_instruction(
  1668. initialize_account(&program_id, &mismatch_key, &mint2_key, &owner_key).unwrap(),
  1669. vec![
  1670. &mut mismatch_account,
  1671. &mut mint2_account,
  1672. &mut owner_account,
  1673. &mut rent_sysvar,
  1674. ],
  1675. )
  1676. .unwrap();
  1677. // create new mint with owner
  1678. do_process_instruction(
  1679. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  1680. vec![&mut mint_account, &mut rent_sysvar],
  1681. )
  1682. .unwrap();
  1683. // mint to
  1684. do_process_instruction(
  1685. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
  1686. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1687. )
  1688. .unwrap();
  1689. let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
  1690. assert_eq!(mint.supply, 42);
  1691. let dest_account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  1692. assert_eq!(dest_account.amount, 42);
  1693. // mint to another account to test supply accumulation
  1694. do_process_instruction(
  1695. mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
  1696. vec![&mut mint_account, &mut account2_account, &mut owner_account],
  1697. )
  1698. .unwrap();
  1699. let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
  1700. assert_eq!(mint.supply, 84);
  1701. let dest_account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
  1702. assert_eq!(dest_account.amount, 42);
  1703. // missing signer
  1704. let mut instruction =
  1705. mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap();
  1706. instruction.accounts[2].is_signer = false;
  1707. assert_eq!(
  1708. Err(ProgramError::MissingRequiredSignature),
  1709. do_process_instruction(
  1710. instruction,
  1711. vec![&mut mint_account, &mut account2_account, &mut owner_account],
  1712. )
  1713. );
  1714. // mismatch account
  1715. assert_eq!(
  1716. Err(TokenError::MintMismatch.into()),
  1717. do_process_instruction(
  1718. mint_to(&program_id, &mint_key, &mismatch_key, &owner_key, &[], 42).unwrap(),
  1719. vec![&mut mint_account, &mut mismatch_account, &mut owner_account],
  1720. )
  1721. );
  1722. // missing owner
  1723. assert_eq!(
  1724. Err(TokenError::OwnerMismatch.into()),
  1725. do_process_instruction(
  1726. mint_to(&program_id, &mint_key, &account2_key, &owner2_key, &[], 42).unwrap(),
  1727. vec![
  1728. &mut mint_account,
  1729. &mut account2_account,
  1730. &mut owner2_account,
  1731. ],
  1732. )
  1733. );
  1734. // uninitialized destination account
  1735. assert_eq!(
  1736. Err(TokenError::UninitializedState.into()),
  1737. do_process_instruction(
  1738. mint_to(
  1739. &program_id,
  1740. &mint_key,
  1741. &uninitialized_key,
  1742. &owner_key,
  1743. &[],
  1744. 42
  1745. )
  1746. .unwrap(),
  1747. vec![
  1748. &mut mint_account,
  1749. &mut uninitialized_account,
  1750. &mut owner_account,
  1751. ],
  1752. )
  1753. );
  1754. // unset mint_authority and test minting fails
  1755. do_process_instruction(
  1756. set_authority(
  1757. &program_id,
  1758. &mint_key,
  1759. None,
  1760. AuthorityType::MintTokens,
  1761. &owner_key,
  1762. &[],
  1763. )
  1764. .unwrap(),
  1765. vec![&mut mint_account, &mut owner_account],
  1766. )
  1767. .unwrap();
  1768. assert_eq!(
  1769. Err(TokenError::FixedSupply.into()),
  1770. do_process_instruction(
  1771. mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
  1772. vec![&mut mint_account, &mut account2_account, &mut owner_account],
  1773. )
  1774. );
  1775. }
  1776. #[test]
  1777. fn test_burn() {
  1778. let program_id = pubkey_rand();
  1779. let account_key = pubkey_rand();
  1780. let mut account_account =
  1781. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1782. let account2_key = pubkey_rand();
  1783. let mut account2_account =
  1784. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1785. let account3_key = pubkey_rand();
  1786. let mut account3_account =
  1787. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1788. let delegate_key = pubkey_rand();
  1789. let mut delegate_account = SolanaAccount::default();
  1790. let mismatch_key = pubkey_rand();
  1791. let mut mismatch_account =
  1792. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1793. let owner_key = pubkey_rand();
  1794. let mut owner_account = SolanaAccount::default();
  1795. let owner2_key = pubkey_rand();
  1796. let mut owner2_account = SolanaAccount::default();
  1797. let mint_key = pubkey_rand();
  1798. let mut mint_account =
  1799. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1800. let mint2_key = pubkey_rand();
  1801. let mut mint2_account =
  1802. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1803. let mut rent_sysvar = rent_sysvar();
  1804. // create account
  1805. do_process_instruction(
  1806. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  1807. vec![
  1808. &mut account_account,
  1809. &mut mint_account,
  1810. &mut owner_account,
  1811. &mut rent_sysvar,
  1812. ],
  1813. )
  1814. .unwrap();
  1815. // create another account
  1816. do_process_instruction(
  1817. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  1818. vec![
  1819. &mut account2_account,
  1820. &mut mint_account,
  1821. &mut owner_account,
  1822. &mut rent_sysvar,
  1823. ],
  1824. )
  1825. .unwrap();
  1826. // create another account
  1827. do_process_instruction(
  1828. initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
  1829. vec![
  1830. &mut account3_account,
  1831. &mut mint_account,
  1832. &mut owner_account,
  1833. &mut rent_sysvar,
  1834. ],
  1835. )
  1836. .unwrap();
  1837. // create mismatch account
  1838. do_process_instruction(
  1839. initialize_account(&program_id, &mismatch_key, &mint2_key, &owner_key).unwrap(),
  1840. vec![
  1841. &mut mismatch_account,
  1842. &mut mint2_account,
  1843. &mut owner_account,
  1844. &mut rent_sysvar,
  1845. ],
  1846. )
  1847. .unwrap();
  1848. // create new mint
  1849. do_process_instruction(
  1850. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  1851. vec![&mut mint_account, &mut rent_sysvar],
  1852. )
  1853. .unwrap();
  1854. do_process_instruction(
  1855. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  1856. vec![&mut mint_account, &mut account_account, &mut owner_account],
  1857. )
  1858. .unwrap();
  1859. // missing signer
  1860. let mut instruction =
  1861. burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 42).unwrap();
  1862. instruction.accounts[1].is_signer = false;
  1863. assert_eq!(
  1864. Err(TokenError::OwnerMismatch.into()),
  1865. do_process_instruction(
  1866. instruction,
  1867. vec![
  1868. &mut account_account,
  1869. &mut mint_account,
  1870. &mut delegate_account
  1871. ],
  1872. )
  1873. );
  1874. // missing owner
  1875. assert_eq!(
  1876. Err(TokenError::OwnerMismatch.into()),
  1877. do_process_instruction(
  1878. burn(&program_id, &account_key, &mint_key, &owner2_key, &[], 42).unwrap(),
  1879. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  1880. )
  1881. );
  1882. // mint mismatch
  1883. assert_eq!(
  1884. Err(TokenError::MintMismatch.into()),
  1885. do_process_instruction(
  1886. burn(&program_id, &mismatch_key, &mint_key, &owner_key, &[], 42).unwrap(),
  1887. vec![&mut mismatch_account, &mut mint_account, &mut owner_account],
  1888. )
  1889. );
  1890. // burn
  1891. do_process_instruction(
  1892. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 42).unwrap(),
  1893. vec![&mut account_account, &mut mint_account, &mut owner_account],
  1894. )
  1895. .unwrap();
  1896. let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
  1897. assert_eq!(mint.supply, 1000 - 42);
  1898. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  1899. assert_eq!(account.amount, 1000 - 42);
  1900. // insufficient funds
  1901. assert_eq!(
  1902. Err(TokenError::InsufficientFunds.into()),
  1903. do_process_instruction(
  1904. burn(
  1905. &program_id,
  1906. &account_key,
  1907. &mint_key,
  1908. &owner_key,
  1909. &[],
  1910. 100_000_000
  1911. )
  1912. .unwrap(),
  1913. vec![&mut account_account, &mut mint_account, &mut owner_account],
  1914. )
  1915. );
  1916. // approve delegate
  1917. do_process_instruction(
  1918. approve(
  1919. &program_id,
  1920. &account_key,
  1921. &delegate_key,
  1922. &owner_key,
  1923. &[],
  1924. 84,
  1925. )
  1926. .unwrap(),
  1927. vec![
  1928. &mut account_account,
  1929. &mut delegate_account,
  1930. &mut owner_account,
  1931. ],
  1932. )
  1933. .unwrap();
  1934. // not a delegate of source account
  1935. assert_eq!(
  1936. Err(TokenError::InsufficientFunds.into()),
  1937. do_process_instruction(
  1938. burn(
  1939. &program_id,
  1940. &account_key,
  1941. &mint_key,
  1942. &owner_key,
  1943. &[],
  1944. 100_000_000
  1945. )
  1946. .unwrap(),
  1947. vec![&mut account_account, &mut mint_account, &mut owner_account],
  1948. )
  1949. );
  1950. // burn via delegate
  1951. do_process_instruction(
  1952. burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 84).unwrap(),
  1953. vec![
  1954. &mut account_account,
  1955. &mut mint_account,
  1956. &mut delegate_account,
  1957. ],
  1958. )
  1959. .unwrap();
  1960. // match
  1961. let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
  1962. assert_eq!(mint.supply, 1000 - 42 - 84);
  1963. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  1964. assert_eq!(account.amount, 1000 - 42 - 84);
  1965. // insufficient funds approved via delegate
  1966. assert_eq!(
  1967. Err(TokenError::OwnerMismatch.into()),
  1968. do_process_instruction(
  1969. burn(
  1970. &program_id,
  1971. &account_key,
  1972. &mint_key,
  1973. &delegate_key,
  1974. &[],
  1975. 100
  1976. )
  1977. .unwrap(),
  1978. vec![
  1979. &mut account_account,
  1980. &mut mint_account,
  1981. &mut delegate_account
  1982. ],
  1983. )
  1984. );
  1985. }
  1986. #[test]
  1987. fn test_multisig() {
  1988. let program_id = pubkey_rand();
  1989. let mint_key = pubkey_rand();
  1990. let mut mint_account =
  1991. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  1992. let account_key = pubkey_rand();
  1993. let mut account =
  1994. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1995. let account2_key = pubkey_rand();
  1996. let mut account2_account =
  1997. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  1998. let owner_key = pubkey_rand();
  1999. let mut owner_account = SolanaAccount::default();
  2000. let multisig_key = pubkey_rand();
  2001. let mut multisig_account = SolanaAccount::new(42, size_of::<Multisig>(), &program_id);
  2002. let multisig_delegate_key = pubkey_rand();
  2003. let mut multisig_delegate_account = SolanaAccount::new(
  2004. multisig_minimum_balance(),
  2005. size_of::<Multisig>(),
  2006. &program_id,
  2007. );
  2008. let signer_keys = vec![pubkey_rand(); MAX_SIGNERS];
  2009. let signer_key_refs: Vec<&Pubkey> = signer_keys.iter().map(|key| key).collect();
  2010. let mut signer_accounts = vec![SolanaAccount::new(0, 0, &program_id); MAX_SIGNERS];
  2011. let mut rent_sysvar = rent_sysvar();
  2012. // multisig is not rent exempt
  2013. let account_info_iter = &mut signer_accounts.iter_mut();
  2014. assert_eq!(
  2015. Err(TokenError::NotRentExempt.into()),
  2016. do_process_instruction(
  2017. initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
  2018. vec![
  2019. &mut multisig_account,
  2020. &mut rent_sysvar,
  2021. &mut account_info_iter.next().unwrap(),
  2022. ],
  2023. )
  2024. );
  2025. multisig_account.lamports = multisig_minimum_balance();
  2026. // single signer
  2027. let account_info_iter = &mut signer_accounts.iter_mut();
  2028. do_process_instruction(
  2029. initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
  2030. vec![
  2031. &mut multisig_account,
  2032. &mut rent_sysvar,
  2033. &mut account_info_iter.next().unwrap(),
  2034. ],
  2035. )
  2036. .unwrap();
  2037. // multiple signer
  2038. let account_info_iter = &mut signer_accounts.iter_mut();
  2039. do_process_instruction(
  2040. initialize_multisig(
  2041. &program_id,
  2042. &multisig_delegate_key,
  2043. &signer_key_refs,
  2044. MAX_SIGNERS as u8,
  2045. )
  2046. .unwrap(),
  2047. vec![
  2048. &mut multisig_delegate_account,
  2049. &mut rent_sysvar,
  2050. &mut account_info_iter.next().unwrap(),
  2051. &mut account_info_iter.next().unwrap(),
  2052. &mut account_info_iter.next().unwrap(),
  2053. &mut account_info_iter.next().unwrap(),
  2054. &mut account_info_iter.next().unwrap(),
  2055. &mut account_info_iter.next().unwrap(),
  2056. &mut account_info_iter.next().unwrap(),
  2057. &mut account_info_iter.next().unwrap(),
  2058. &mut account_info_iter.next().unwrap(),
  2059. &mut account_info_iter.next().unwrap(),
  2060. &mut account_info_iter.next().unwrap(),
  2061. ],
  2062. )
  2063. .unwrap();
  2064. // create account with multisig owner
  2065. do_process_instruction(
  2066. initialize_account(&program_id, &account_key, &mint_key, &multisig_key).unwrap(),
  2067. vec![
  2068. &mut account,
  2069. &mut mint_account,
  2070. &mut multisig_account,
  2071. &mut rent_sysvar,
  2072. ],
  2073. )
  2074. .unwrap();
  2075. // create another account with multisig owner
  2076. do_process_instruction(
  2077. initialize_account(
  2078. &program_id,
  2079. &account2_key,
  2080. &mint_key,
  2081. &multisig_delegate_key,
  2082. )
  2083. .unwrap(),
  2084. vec![
  2085. &mut account2_account,
  2086. &mut mint_account,
  2087. &mut multisig_account,
  2088. &mut rent_sysvar,
  2089. ],
  2090. )
  2091. .unwrap();
  2092. // create new mint with multisig owner
  2093. do_process_instruction(
  2094. initialize_mint(&program_id, &mint_key, &multisig_key, None, 2).unwrap(),
  2095. vec![&mut mint_account, &mut rent_sysvar],
  2096. )
  2097. .unwrap();
  2098. let account_info_iter = &mut signer_accounts.iter_mut();
  2099. do_process_instruction(
  2100. mint_to(
  2101. &program_id,
  2102. &mint_key,
  2103. &account_key,
  2104. &multisig_key,
  2105. &[&signer_keys[0]],
  2106. 1000,
  2107. )
  2108. .unwrap(),
  2109. vec![
  2110. &mut mint_account,
  2111. &mut account,
  2112. &mut multisig_account,
  2113. &mut account_info_iter.next().unwrap(),
  2114. ],
  2115. )
  2116. .unwrap();
  2117. // approve
  2118. let account_info_iter = &mut signer_accounts.iter_mut();
  2119. do_process_instruction(
  2120. approve(
  2121. &program_id,
  2122. &account_key,
  2123. &multisig_delegate_key,
  2124. &multisig_key,
  2125. &[&signer_keys[0]],
  2126. 100,
  2127. )
  2128. .unwrap(),
  2129. vec![
  2130. &mut account,
  2131. &mut multisig_delegate_account,
  2132. &mut multisig_account,
  2133. &mut account_info_iter.next().unwrap(),
  2134. ],
  2135. )
  2136. .unwrap();
  2137. // transfer
  2138. let account_info_iter = &mut signer_accounts.iter_mut();
  2139. do_process_instruction(
  2140. transfer(
  2141. &program_id,
  2142. &account_key,
  2143. &account2_key,
  2144. &multisig_key,
  2145. &[&signer_keys[0]],
  2146. 42,
  2147. )
  2148. .unwrap(),
  2149. vec![
  2150. &mut account,
  2151. &mut account2_account,
  2152. &mut multisig_account,
  2153. &mut account_info_iter.next().unwrap(),
  2154. ],
  2155. )
  2156. .unwrap();
  2157. // transfer via delegate
  2158. let account_info_iter = &mut signer_accounts.iter_mut();
  2159. do_process_instruction(
  2160. transfer(
  2161. &program_id,
  2162. &account_key,
  2163. &account2_key,
  2164. &multisig_delegate_key,
  2165. &signer_key_refs,
  2166. 42,
  2167. )
  2168. .unwrap(),
  2169. vec![
  2170. &mut account,
  2171. &mut account2_account,
  2172. &mut multisig_delegate_account,
  2173. &mut account_info_iter.next().unwrap(),
  2174. &mut account_info_iter.next().unwrap(),
  2175. &mut account_info_iter.next().unwrap(),
  2176. &mut account_info_iter.next().unwrap(),
  2177. &mut account_info_iter.next().unwrap(),
  2178. &mut account_info_iter.next().unwrap(),
  2179. &mut account_info_iter.next().unwrap(),
  2180. &mut account_info_iter.next().unwrap(),
  2181. &mut account_info_iter.next().unwrap(),
  2182. &mut account_info_iter.next().unwrap(),
  2183. &mut account_info_iter.next().unwrap(),
  2184. ],
  2185. )
  2186. .unwrap();
  2187. // mint to
  2188. let account_info_iter = &mut signer_accounts.iter_mut();
  2189. do_process_instruction(
  2190. mint_to(
  2191. &program_id,
  2192. &mint_key,
  2193. &account2_key,
  2194. &multisig_key,
  2195. &[&signer_keys[0]],
  2196. 42,
  2197. )
  2198. .unwrap(),
  2199. vec![
  2200. &mut mint_account,
  2201. &mut account2_account,
  2202. &mut multisig_account,
  2203. &mut account_info_iter.next().unwrap(),
  2204. ],
  2205. )
  2206. .unwrap();
  2207. // burn
  2208. let account_info_iter = &mut signer_accounts.iter_mut();
  2209. do_process_instruction(
  2210. burn(
  2211. &program_id,
  2212. &account_key,
  2213. &mint_key,
  2214. &multisig_key,
  2215. &[&signer_keys[0]],
  2216. 42,
  2217. )
  2218. .unwrap(),
  2219. vec![
  2220. &mut account,
  2221. &mut mint_account,
  2222. &mut multisig_account,
  2223. &mut account_info_iter.next().unwrap(),
  2224. ],
  2225. )
  2226. .unwrap();
  2227. // burn via delegate
  2228. let account_info_iter = &mut signer_accounts.iter_mut();
  2229. do_process_instruction(
  2230. burn(
  2231. &program_id,
  2232. &account_key,
  2233. &mint_key,
  2234. &multisig_delegate_key,
  2235. &signer_key_refs,
  2236. 42,
  2237. )
  2238. .unwrap(),
  2239. vec![
  2240. &mut account,
  2241. &mut mint_account,
  2242. &mut multisig_delegate_account,
  2243. &mut account_info_iter.next().unwrap(),
  2244. &mut account_info_iter.next().unwrap(),
  2245. &mut account_info_iter.next().unwrap(),
  2246. &mut account_info_iter.next().unwrap(),
  2247. &mut account_info_iter.next().unwrap(),
  2248. &mut account_info_iter.next().unwrap(),
  2249. &mut account_info_iter.next().unwrap(),
  2250. &mut account_info_iter.next().unwrap(),
  2251. &mut account_info_iter.next().unwrap(),
  2252. &mut account_info_iter.next().unwrap(),
  2253. &mut account_info_iter.next().unwrap(),
  2254. ],
  2255. )
  2256. .unwrap();
  2257. // freeze account
  2258. let account3_key = pubkey_rand();
  2259. let mut account3_account =
  2260. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2261. let mint2_key = pubkey_rand();
  2262. let mut mint2_account =
  2263. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  2264. do_process_instruction(
  2265. initialize_account(&program_id, &account3_key, &mint2_key, &owner_key).unwrap(),
  2266. vec![
  2267. &mut account3_account,
  2268. &mut mint2_account,
  2269. &mut owner_account,
  2270. &mut rent_sysvar,
  2271. ],
  2272. )
  2273. .unwrap();
  2274. do_process_instruction(
  2275. initialize_mint(
  2276. &program_id,
  2277. &mint2_key,
  2278. &multisig_key,
  2279. Some(&multisig_key),
  2280. 2,
  2281. )
  2282. .unwrap(),
  2283. vec![&mut mint2_account, &mut rent_sysvar],
  2284. )
  2285. .unwrap();
  2286. let account_info_iter = &mut signer_accounts.iter_mut();
  2287. do_process_instruction(
  2288. mint_to(
  2289. &program_id,
  2290. &mint2_key,
  2291. &account3_key,
  2292. &multisig_key,
  2293. &[&signer_keys[0]],
  2294. 1000,
  2295. )
  2296. .unwrap(),
  2297. vec![
  2298. &mut mint2_account,
  2299. &mut account3_account,
  2300. &mut multisig_account,
  2301. &mut account_info_iter.next().unwrap(),
  2302. ],
  2303. )
  2304. .unwrap();
  2305. let account_info_iter = &mut signer_accounts.iter_mut();
  2306. do_process_instruction(
  2307. freeze_account(
  2308. &program_id,
  2309. &account3_key,
  2310. &mint2_key,
  2311. &multisig_key,
  2312. &[&signer_keys[0]],
  2313. )
  2314. .unwrap(),
  2315. vec![
  2316. &mut account3_account,
  2317. &mut mint2_account,
  2318. &mut multisig_account,
  2319. &mut account_info_iter.next().unwrap(),
  2320. ],
  2321. )
  2322. .unwrap();
  2323. // do SetAuthority on mint
  2324. let account_info_iter = &mut signer_accounts.iter_mut();
  2325. do_process_instruction(
  2326. set_authority(
  2327. &program_id,
  2328. &mint_key,
  2329. Some(&owner_key),
  2330. AuthorityType::MintTokens,
  2331. &multisig_key,
  2332. &[&signer_keys[0]],
  2333. )
  2334. .unwrap(),
  2335. vec![
  2336. &mut mint_account,
  2337. &mut multisig_account,
  2338. &mut account_info_iter.next().unwrap(),
  2339. ],
  2340. )
  2341. .unwrap();
  2342. // do SetAuthority on account
  2343. let account_info_iter = &mut signer_accounts.iter_mut();
  2344. do_process_instruction(
  2345. set_authority(
  2346. &program_id,
  2347. &account_key,
  2348. Some(&owner_key),
  2349. AuthorityType::AccountHolder,
  2350. &multisig_key,
  2351. &[&signer_keys[0]],
  2352. )
  2353. .unwrap(),
  2354. vec![
  2355. &mut account,
  2356. &mut multisig_account,
  2357. &mut account_info_iter.next().unwrap(),
  2358. ],
  2359. )
  2360. .unwrap();
  2361. }
  2362. #[test]
  2363. fn test_validate_owner() {
  2364. let program_id = pubkey_rand();
  2365. let owner_key = pubkey_rand();
  2366. let mut signer_keys = [Pubkey::default(); MAX_SIGNERS];
  2367. for signer_key in signer_keys.iter_mut().take(MAX_SIGNERS) {
  2368. *signer_key = pubkey_rand();
  2369. }
  2370. let mut signer_lamports = 0;
  2371. let mut signer_data = vec![];
  2372. let mut signers = vec![
  2373. AccountInfo::new(
  2374. &owner_key,
  2375. true,
  2376. false,
  2377. &mut signer_lamports,
  2378. &mut signer_data,
  2379. &program_id,
  2380. false,
  2381. Epoch::default(),
  2382. );
  2383. MAX_SIGNERS + 1
  2384. ];
  2385. for (signer, key) in signers.iter_mut().zip(&signer_keys) {
  2386. signer.key = key;
  2387. }
  2388. let mut lamports = 0;
  2389. let mut data = vec![0; size_of::<Multisig>()];
  2390. let mut multisig: &mut Multisig = state::unpack_unchecked(&mut data).unwrap();
  2391. multisig.m = MAX_SIGNERS as u8;
  2392. multisig.n = MAX_SIGNERS as u8;
  2393. multisig.signers = signer_keys;
  2394. multisig.is_initialized = true;
  2395. let owner_account_info = AccountInfo::new(
  2396. &owner_key,
  2397. false,
  2398. false,
  2399. &mut lamports,
  2400. &mut data,
  2401. &program_id,
  2402. false,
  2403. Epoch::default(),
  2404. );
  2405. // full 11 of 11
  2406. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
  2407. // 1 of 11
  2408. {
  2409. let mut data_ref_mut = owner_account_info.data.borrow_mut();
  2410. let mut multisig: &mut Multisig = state::unpack(&mut data_ref_mut).unwrap();
  2411. multisig.m = 1;
  2412. }
  2413. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
  2414. // 2:1
  2415. {
  2416. let mut data_ref_mut = owner_account_info.data.borrow_mut();
  2417. let mut multisig: &mut Multisig = state::unpack(&mut data_ref_mut).unwrap();
  2418. multisig.m = 2;
  2419. multisig.n = 1;
  2420. }
  2421. assert_eq!(
  2422. Err(ProgramError::MissingRequiredSignature),
  2423. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
  2424. );
  2425. // 0:11
  2426. {
  2427. let mut data_ref_mut = owner_account_info.data.borrow_mut();
  2428. let mut multisig: &mut Multisig = state::unpack(&mut data_ref_mut).unwrap();
  2429. multisig.m = 0;
  2430. multisig.n = 11;
  2431. }
  2432. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
  2433. // 2:11 but 0 provided
  2434. {
  2435. let mut data_ref_mut = owner_account_info.data.borrow_mut();
  2436. let mut multisig: &mut Multisig = state::unpack(&mut data_ref_mut).unwrap();
  2437. multisig.m = 2;
  2438. multisig.n = 11;
  2439. }
  2440. assert_eq!(
  2441. Err(ProgramError::MissingRequiredSignature),
  2442. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &[])
  2443. );
  2444. // 2:11 but 1 provided
  2445. {
  2446. let mut data_ref_mut = owner_account_info.data.borrow_mut();
  2447. let mut multisig: &mut Multisig = state::unpack(&mut data_ref_mut).unwrap();
  2448. multisig.m = 2;
  2449. multisig.n = 11;
  2450. }
  2451. assert_eq!(
  2452. Err(ProgramError::MissingRequiredSignature),
  2453. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[0..1])
  2454. );
  2455. // 2:11, 2 from middle provided
  2456. {
  2457. let mut data_ref_mut = owner_account_info.data.borrow_mut();
  2458. let mut multisig: &mut Multisig = state::unpack(&mut data_ref_mut).unwrap();
  2459. multisig.m = 2;
  2460. multisig.n = 11;
  2461. }
  2462. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[5..7])
  2463. .unwrap();
  2464. // 11:11, one is not a signer
  2465. {
  2466. let mut data_ref_mut = owner_account_info.data.borrow_mut();
  2467. let mut multisig: &mut Multisig = state::unpack(&mut data_ref_mut).unwrap();
  2468. multisig.m = 2;
  2469. multisig.n = 11;
  2470. }
  2471. signers[5].is_signer = false;
  2472. assert_eq!(
  2473. Err(ProgramError::MissingRequiredSignature),
  2474. Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
  2475. );
  2476. signers[5].is_signer = true;
  2477. }
  2478. #[test]
  2479. fn test_close_account() {
  2480. let program_id = pubkey_rand();
  2481. let mint_key = pubkey_rand();
  2482. let mut mint_account =
  2483. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  2484. let account_key = pubkey_rand();
  2485. let mut account_account =
  2486. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2487. let account2_key = pubkey_rand();
  2488. let mut account2_account = SolanaAccount::new(
  2489. account_minimum_balance() + 42,
  2490. size_of::<Account>(),
  2491. &program_id,
  2492. );
  2493. let account3_key = pubkey_rand();
  2494. let mut account3_account =
  2495. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2496. let owner_key = pubkey_rand();
  2497. let mut owner_account = SolanaAccount::default();
  2498. let owner2_key = pubkey_rand();
  2499. let mut owner2_account = SolanaAccount::default();
  2500. let mut rent_sysvar = rent_sysvar();
  2501. // uninitialized
  2502. assert_eq!(
  2503. Err(TokenError::UninitializedState.into()),
  2504. do_process_instruction(
  2505. close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
  2506. vec![
  2507. &mut account_account,
  2508. &mut account3_account,
  2509. &mut owner2_account,
  2510. ],
  2511. )
  2512. );
  2513. // initialize and mint to non-native account
  2514. do_process_instruction(
  2515. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  2516. vec![
  2517. &mut account_account,
  2518. &mut mint_account,
  2519. &mut owner_account,
  2520. &mut rent_sysvar,
  2521. ],
  2522. )
  2523. .unwrap();
  2524. do_process_instruction(
  2525. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  2526. vec![&mut mint_account, &mut rent_sysvar],
  2527. )
  2528. .unwrap();
  2529. do_process_instruction(
  2530. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
  2531. vec![
  2532. &mut mint_account,
  2533. &mut account_account,
  2534. &mut owner_account,
  2535. &mut rent_sysvar,
  2536. ],
  2537. )
  2538. .unwrap();
  2539. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  2540. assert_eq!(account.amount, 42);
  2541. // initialize native account
  2542. do_process_instruction(
  2543. initialize_account(
  2544. &program_id,
  2545. &account2_key,
  2546. &crate::native_mint::id(),
  2547. &owner_key,
  2548. )
  2549. .unwrap(),
  2550. vec![
  2551. &mut account2_account,
  2552. &mut mint_account,
  2553. &mut owner_account,
  2554. &mut rent_sysvar,
  2555. ],
  2556. )
  2557. .unwrap();
  2558. let account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
  2559. assert!(account.is_native());
  2560. assert_eq!(account.amount, 42);
  2561. // close non-native account with balance
  2562. assert_eq!(
  2563. Err(TokenError::NonNativeHasBalance.into()),
  2564. do_process_instruction(
  2565. close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
  2566. vec![
  2567. &mut account_account,
  2568. &mut account3_account,
  2569. &mut owner_account,
  2570. ],
  2571. )
  2572. );
  2573. assert_eq!(account_account.lamports, account_minimum_balance());
  2574. // empty account
  2575. do_process_instruction(
  2576. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 42).unwrap(),
  2577. vec![&mut account_account, &mut mint_account, &mut owner_account],
  2578. )
  2579. .unwrap();
  2580. // wrong owner
  2581. assert_eq!(
  2582. Err(TokenError::OwnerMismatch.into()),
  2583. do_process_instruction(
  2584. close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
  2585. vec![
  2586. &mut account_account,
  2587. &mut account3_account,
  2588. &mut owner2_account,
  2589. ],
  2590. )
  2591. );
  2592. // close account
  2593. do_process_instruction(
  2594. close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
  2595. vec![
  2596. &mut account_account,
  2597. &mut account3_account,
  2598. &mut owner_account,
  2599. ],
  2600. )
  2601. .unwrap();
  2602. let account: &mut Account = state::unpack_unchecked(&mut account_account.data).unwrap();
  2603. assert_eq!(account_account.lamports, 0);
  2604. assert_eq!(account.amount, 0);
  2605. assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
  2606. // fund and initialize new non-native account to test close authority
  2607. let account_key = pubkey_rand();
  2608. let mut account_account =
  2609. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2610. let owner2_key = pubkey_rand();
  2611. let mut owner2_account =
  2612. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2613. do_process_instruction(
  2614. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  2615. vec![
  2616. &mut account_account,
  2617. &mut mint_account,
  2618. &mut owner_account,
  2619. &mut rent_sysvar,
  2620. ],
  2621. )
  2622. .unwrap();
  2623. account_account.lamports = 2;
  2624. do_process_instruction(
  2625. set_authority(
  2626. &program_id,
  2627. &account_key,
  2628. Some(&owner2_key),
  2629. AuthorityType::CloseAccount,
  2630. &owner_key,
  2631. &[],
  2632. )
  2633. .unwrap(),
  2634. vec![&mut account_account, &mut owner_account],
  2635. )
  2636. .unwrap();
  2637. // account owner cannot authorize close if close_authority is set
  2638. assert_eq!(
  2639. Err(TokenError::OwnerMismatch.into()),
  2640. do_process_instruction(
  2641. close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
  2642. vec![
  2643. &mut account_account,
  2644. &mut account3_account,
  2645. &mut owner_account,
  2646. ],
  2647. )
  2648. );
  2649. // close non-native account with close_authority
  2650. do_process_instruction(
  2651. close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
  2652. vec![
  2653. &mut account_account,
  2654. &mut account3_account,
  2655. &mut owner2_account,
  2656. ],
  2657. )
  2658. .unwrap();
  2659. assert_eq!(account_account.lamports, 0);
  2660. assert_eq!(account.amount, 0);
  2661. assert_eq!(account3_account.lamports, 2 * account_minimum_balance() + 2);
  2662. // close native account
  2663. do_process_instruction(
  2664. close_account(&program_id, &account2_key, &account3_key, &owner_key, &[]).unwrap(),
  2665. vec![
  2666. &mut account2_account,
  2667. &mut account3_account,
  2668. &mut owner_account,
  2669. ],
  2670. )
  2671. .unwrap();
  2672. let account: &mut Account = state::unpack_unchecked(&mut account2_account.data).unwrap();
  2673. assert!(account.is_native());
  2674. assert_eq!(account_account.lamports, 0);
  2675. assert_eq!(account.amount, 0);
  2676. assert_eq!(
  2677. account3_account.lamports,
  2678. 3 * account_minimum_balance() + 2 + 42
  2679. );
  2680. }
  2681. #[test]
  2682. fn test_native_token() {
  2683. let program_id = pubkey_rand();
  2684. let mut mint_account =
  2685. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  2686. let account_key = pubkey_rand();
  2687. let mut account_account = SolanaAccount::new(
  2688. account_minimum_balance() + 40,
  2689. size_of::<Account>(),
  2690. &program_id,
  2691. );
  2692. let account2_key = pubkey_rand();
  2693. let mut account2_account =
  2694. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2695. let account3_key = pubkey_rand();
  2696. let mut account3_account = SolanaAccount::new(account_minimum_balance(), 0, &program_id);
  2697. let owner_key = pubkey_rand();
  2698. let mut owner_account = SolanaAccount::default();
  2699. let mut rent_sysvar = rent_sysvar();
  2700. // initialize native account
  2701. do_process_instruction(
  2702. initialize_account(
  2703. &program_id,
  2704. &account_key,
  2705. &crate::native_mint::id(),
  2706. &owner_key,
  2707. )
  2708. .unwrap(),
  2709. vec![
  2710. &mut account_account,
  2711. &mut mint_account,
  2712. &mut owner_account,
  2713. &mut rent_sysvar,
  2714. ],
  2715. )
  2716. .unwrap();
  2717. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  2718. assert!(account.is_native());
  2719. assert_eq!(account.amount, 40);
  2720. // initialize native account
  2721. do_process_instruction(
  2722. initialize_account(
  2723. &program_id,
  2724. &account2_key,
  2725. &crate::native_mint::id(),
  2726. &owner_key,
  2727. )
  2728. .unwrap(),
  2729. vec![
  2730. &mut account2_account,
  2731. &mut mint_account,
  2732. &mut owner_account,
  2733. &mut rent_sysvar,
  2734. ],
  2735. )
  2736. .unwrap();
  2737. let account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
  2738. assert!(account.is_native());
  2739. assert_eq!(account.amount, 0);
  2740. // mint_to unsupported
  2741. assert_eq!(
  2742. Err(TokenError::NativeNotSupported.into()),
  2743. do_process_instruction(
  2744. mint_to(
  2745. &program_id,
  2746. &crate::native_mint::id(),
  2747. &account_key,
  2748. &owner_key,
  2749. &[],
  2750. 42
  2751. )
  2752. .unwrap(),
  2753. vec![&mut mint_account, &mut account_account, &mut owner_account],
  2754. )
  2755. );
  2756. // burn unsupported
  2757. let bogus_mint_key = pubkey_rand();
  2758. let mut bogus_mint_account =
  2759. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  2760. do_process_instruction(
  2761. initialize_mint(&program_id, &bogus_mint_key, &owner_key, None, 2).unwrap(),
  2762. vec![&mut bogus_mint_account, &mut rent_sysvar],
  2763. )
  2764. .unwrap();
  2765. assert_eq!(
  2766. Err(TokenError::NativeNotSupported.into()),
  2767. do_process_instruction(
  2768. burn(
  2769. &program_id,
  2770. &account_key,
  2771. &bogus_mint_key,
  2772. &owner_key,
  2773. &[],
  2774. 42
  2775. )
  2776. .unwrap(),
  2777. vec![
  2778. &mut account_account,
  2779. &mut bogus_mint_account,
  2780. &mut owner_account
  2781. ],
  2782. )
  2783. );
  2784. // ensure can't transfer below rent-exempt reserve
  2785. assert_eq!(
  2786. Err(TokenError::InsufficientFunds.into()),
  2787. do_process_instruction(
  2788. transfer(
  2789. &program_id,
  2790. &account_key,
  2791. &account2_key,
  2792. &owner_key,
  2793. &[],
  2794. 50,
  2795. )
  2796. .unwrap(),
  2797. vec![
  2798. &mut account_account,
  2799. &mut account2_account,
  2800. &mut owner_account,
  2801. ],
  2802. )
  2803. );
  2804. // transfer between native accounts
  2805. do_process_instruction(
  2806. transfer(
  2807. &program_id,
  2808. &account_key,
  2809. &account2_key,
  2810. &owner_key,
  2811. &[],
  2812. 40,
  2813. )
  2814. .unwrap(),
  2815. vec![
  2816. &mut account_account,
  2817. &mut account2_account,
  2818. &mut owner_account,
  2819. ],
  2820. )
  2821. .unwrap();
  2822. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  2823. assert!(account.is_native());
  2824. assert_eq!(account_account.lamports, account_minimum_balance());
  2825. assert_eq!(account.amount, 0);
  2826. let account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
  2827. assert!(account.is_native());
  2828. assert_eq!(account2_account.lamports, account_minimum_balance() + 40);
  2829. assert_eq!(account.amount, 40);
  2830. // close native account
  2831. do_process_instruction(
  2832. close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
  2833. vec![
  2834. &mut account_account,
  2835. &mut account3_account,
  2836. &mut owner_account,
  2837. ],
  2838. )
  2839. .unwrap();
  2840. let account: &mut Account = state::unpack_unchecked(&mut account_account.data).unwrap();
  2841. assert!(account.is_native());
  2842. assert_eq!(account_account.lamports, 0);
  2843. assert_eq!(account.amount, 0);
  2844. assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
  2845. }
  2846. #[test]
  2847. fn test_overflow() {
  2848. let program_id = pubkey_rand();
  2849. let account_key = pubkey_rand();
  2850. let mut account_account =
  2851. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2852. let account2_key = pubkey_rand();
  2853. let mut account2_account =
  2854. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  2855. let owner_key = pubkey_rand();
  2856. let mut owner_account = SolanaAccount::default();
  2857. let owner2_key = pubkey_rand();
  2858. let mut owner2_account = SolanaAccount::default();
  2859. let mint_owner_key = pubkey_rand();
  2860. let mut mint_owner_account = SolanaAccount::default();
  2861. let mint_key = pubkey_rand();
  2862. let mut mint_account =
  2863. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  2864. let mut rent_sysvar = rent_sysvar();
  2865. // create an account
  2866. do_process_instruction(
  2867. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  2868. vec![
  2869. &mut account_account,
  2870. &mut mint_account,
  2871. &mut owner_account,
  2872. &mut rent_sysvar,
  2873. ],
  2874. )
  2875. .unwrap();
  2876. // create another account
  2877. do_process_instruction(
  2878. initialize_account(&program_id, &account2_key, &mint_key, &owner2_key).unwrap(),
  2879. vec![
  2880. &mut account2_account,
  2881. &mut mint_account,
  2882. &mut owner2_account,
  2883. &mut rent_sysvar,
  2884. ],
  2885. )
  2886. .unwrap();
  2887. // create new mint with owner
  2888. do_process_instruction(
  2889. initialize_mint(&program_id, &mint_key, &mint_owner_key, None, 2).unwrap(),
  2890. vec![&mut mint_account, &mut rent_sysvar],
  2891. )
  2892. .unwrap();
  2893. // mint the max to an account
  2894. do_process_instruction(
  2895. mint_to(
  2896. &program_id,
  2897. &mint_key,
  2898. &account_key,
  2899. &mint_owner_key,
  2900. &[],
  2901. u64::MAX,
  2902. )
  2903. .unwrap(),
  2904. vec![
  2905. &mut mint_account,
  2906. &mut account_account,
  2907. &mut mint_owner_account,
  2908. ],
  2909. )
  2910. .unwrap();
  2911. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  2912. assert_eq!(account.amount, u64::MAX);
  2913. // attempt to mint one more to account
  2914. assert_eq!(
  2915. Err(TokenError::Overflow.into()),
  2916. do_process_instruction(
  2917. mint_to(
  2918. &program_id,
  2919. &mint_key,
  2920. &account_key,
  2921. &mint_owner_key,
  2922. &[],
  2923. 1,
  2924. )
  2925. .unwrap(),
  2926. vec![
  2927. &mut mint_account,
  2928. &mut account_account,
  2929. &mut mint_owner_account,
  2930. ],
  2931. )
  2932. );
  2933. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  2934. assert_eq!(account.amount, u64::MAX);
  2935. // atttempt to mint one more to the other account
  2936. assert_eq!(
  2937. Err(TokenError::Overflow.into()),
  2938. do_process_instruction(
  2939. mint_to(
  2940. &program_id,
  2941. &mint_key,
  2942. &account2_key,
  2943. &mint_owner_key,
  2944. &[],
  2945. 1,
  2946. )
  2947. .unwrap(),
  2948. vec![
  2949. &mut mint_account,
  2950. &mut account2_account,
  2951. &mut mint_owner_account,
  2952. ],
  2953. )
  2954. );
  2955. // burn some of the supply
  2956. do_process_instruction(
  2957. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
  2958. vec![&mut account_account, &mut mint_account, &mut owner_account],
  2959. )
  2960. .unwrap();
  2961. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  2962. assert_eq!(account.amount, u64::MAX - 100);
  2963. do_process_instruction(
  2964. mint_to(
  2965. &program_id,
  2966. &mint_key,
  2967. &account_key,
  2968. &mint_owner_key,
  2969. &[],
  2970. 100,
  2971. )
  2972. .unwrap(),
  2973. vec![
  2974. &mut mint_account,
  2975. &mut account_account,
  2976. &mut mint_owner_account,
  2977. ],
  2978. )
  2979. .unwrap();
  2980. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  2981. assert_eq!(account.amount, u64::MAX);
  2982. // manipulate account balance to attempt overflow transfer
  2983. let account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
  2984. account.amount = 1;
  2985. assert_eq!(
  2986. Err(TokenError::Overflow.into()),
  2987. do_process_instruction(
  2988. transfer(
  2989. &program_id,
  2990. &account2_key,
  2991. &account_key,
  2992. &owner2_key,
  2993. &[],
  2994. 1,
  2995. )
  2996. .unwrap(),
  2997. vec![
  2998. &mut account2_account,
  2999. &mut account_account,
  3000. &mut owner2_account,
  3001. ],
  3002. )
  3003. );
  3004. }
  3005. #[test]
  3006. fn test_frozen() {
  3007. let program_id = pubkey_rand();
  3008. let account_key = pubkey_rand();
  3009. let mut account_account =
  3010. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  3011. let account2_key = pubkey_rand();
  3012. let mut account2_account =
  3013. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  3014. let owner_key = pubkey_rand();
  3015. let mut owner_account = SolanaAccount::default();
  3016. let mint_key = pubkey_rand();
  3017. let mut mint_account =
  3018. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  3019. let mut rent_sysvar = rent_sysvar();
  3020. // create account
  3021. do_process_instruction(
  3022. initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
  3023. vec![
  3024. &mut account_account,
  3025. &mut mint_account,
  3026. &mut owner_account,
  3027. &mut rent_sysvar,
  3028. ],
  3029. )
  3030. .unwrap();
  3031. // create another account
  3032. do_process_instruction(
  3033. initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
  3034. vec![
  3035. &mut account2_account,
  3036. &mut mint_account,
  3037. &mut owner_account,
  3038. &mut rent_sysvar,
  3039. ],
  3040. )
  3041. .unwrap();
  3042. // create new mint and fund first account
  3043. do_process_instruction(
  3044. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  3045. vec![&mut mint_account, &mut rent_sysvar],
  3046. )
  3047. .unwrap();
  3048. do_process_instruction(
  3049. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  3050. vec![&mut mint_account, &mut account_account, &mut owner_account],
  3051. )
  3052. .unwrap();
  3053. // no transfer if either account is frozen
  3054. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  3055. account.state = AccountState::Frozen;
  3056. assert_eq!(
  3057. Err(TokenError::AccountFrozen.into()),
  3058. do_process_instruction(
  3059. transfer(
  3060. &program_id,
  3061. &account_key,
  3062. &account2_key,
  3063. &owner_key,
  3064. &[],
  3065. 500,
  3066. )
  3067. .unwrap(),
  3068. vec![
  3069. &mut account_account,
  3070. &mut account2_account,
  3071. &mut owner_account,
  3072. ],
  3073. )
  3074. );
  3075. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  3076. account.state = AccountState::Initialized;
  3077. let account2: &mut Account = state::unpack(&mut account2_account.data).unwrap();
  3078. account2.state = AccountState::Frozen;
  3079. assert_eq!(
  3080. Err(TokenError::AccountFrozen.into()),
  3081. do_process_instruction(
  3082. transfer(
  3083. &program_id,
  3084. &account_key,
  3085. &account2_key,
  3086. &owner_key,
  3087. &[],
  3088. 500,
  3089. )
  3090. .unwrap(),
  3091. vec![
  3092. &mut account_account,
  3093. &mut account2_account,
  3094. &mut owner_account,
  3095. ],
  3096. )
  3097. );
  3098. // no approve if account is frozen
  3099. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  3100. account.state = AccountState::Frozen;
  3101. let delegate_key = pubkey_rand();
  3102. let mut delegate_account = SolanaAccount::default();
  3103. assert_eq!(
  3104. Err(TokenError::AccountFrozen.into()),
  3105. do_process_instruction(
  3106. approve(
  3107. &program_id,
  3108. &account_key,
  3109. &delegate_key,
  3110. &owner_key,
  3111. &[],
  3112. 100
  3113. )
  3114. .unwrap(),
  3115. vec![
  3116. &mut account_account,
  3117. &mut delegate_account,
  3118. &mut owner_account,
  3119. ],
  3120. )
  3121. );
  3122. // no revoke if account is frozen
  3123. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  3124. account.delegate = COption::Some(delegate_key);
  3125. account.delegated_amount = 100;
  3126. assert_eq!(
  3127. Err(TokenError::AccountFrozen.into()),
  3128. do_process_instruction(
  3129. revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
  3130. vec![&mut account_account, &mut owner_account],
  3131. )
  3132. );
  3133. // no set authority if account is frozen
  3134. let new_owner_key = pubkey_rand();
  3135. assert_eq!(
  3136. Err(TokenError::AccountFrozen.into()),
  3137. do_process_instruction(
  3138. set_authority(
  3139. &program_id,
  3140. &account_key,
  3141. Some(&new_owner_key),
  3142. AuthorityType::AccountHolder,
  3143. &owner_key,
  3144. &[]
  3145. )
  3146. .unwrap(),
  3147. vec![&mut account_account, &mut owner_account,],
  3148. )
  3149. );
  3150. // no mint_to if destination account is frozen
  3151. assert_eq!(
  3152. Err(TokenError::AccountFrozen.into()),
  3153. do_process_instruction(
  3154. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 100).unwrap(),
  3155. vec![&mut mint_account, &mut account_account, &mut owner_account,],
  3156. )
  3157. );
  3158. // no burn if account is frozen
  3159. assert_eq!(
  3160. Err(TokenError::AccountFrozen.into()),
  3161. do_process_instruction(
  3162. burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
  3163. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3164. )
  3165. );
  3166. }
  3167. #[test]
  3168. fn test_freeze_account() {
  3169. let program_id = pubkey_rand();
  3170. let account_key = pubkey_rand();
  3171. let mut account_account =
  3172. SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
  3173. let account_owner_key = pubkey_rand();
  3174. let mut account_owner_account = SolanaAccount::default();
  3175. let owner_key = pubkey_rand();
  3176. let mut owner_account = SolanaAccount::default();
  3177. let owner2_key = pubkey_rand();
  3178. let mut owner2_account = SolanaAccount::default();
  3179. let mint_key = pubkey_rand();
  3180. let mut mint_account =
  3181. SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
  3182. let mut rent_sysvar = rent_sysvar();
  3183. // create account
  3184. do_process_instruction(
  3185. initialize_account(&program_id, &account_key, &mint_key, &account_owner_key).unwrap(),
  3186. vec![
  3187. &mut account_account,
  3188. &mut mint_account,
  3189. &mut account_owner_account,
  3190. &mut rent_sysvar,
  3191. ],
  3192. )
  3193. .unwrap();
  3194. // create new mint with owner different from account owner
  3195. do_process_instruction(
  3196. initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
  3197. vec![&mut mint_account, &mut rent_sysvar],
  3198. )
  3199. .unwrap();
  3200. do_process_instruction(
  3201. mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
  3202. vec![&mut mint_account, &mut account_account, &mut owner_account],
  3203. )
  3204. .unwrap();
  3205. // mint cannot freeze
  3206. assert_eq!(
  3207. Err(TokenError::MintCannotFreeze.into()),
  3208. do_process_instruction(
  3209. freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  3210. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3211. )
  3212. );
  3213. // missing freeze_authority
  3214. let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
  3215. mint.freeze_authority = COption::Some(owner_key);
  3216. assert_eq!(
  3217. Err(TokenError::OwnerMismatch.into()),
  3218. do_process_instruction(
  3219. freeze_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
  3220. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  3221. )
  3222. );
  3223. // check explicit thaw
  3224. assert_eq!(
  3225. Err(TokenError::InvalidState.into()),
  3226. do_process_instruction(
  3227. thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
  3228. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  3229. )
  3230. );
  3231. // freeze
  3232. do_process_instruction(
  3233. freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  3234. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3235. )
  3236. .unwrap();
  3237. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  3238. assert_eq!(account.state, AccountState::Frozen);
  3239. // check explicit freeze
  3240. assert_eq!(
  3241. Err(TokenError::InvalidState.into()),
  3242. do_process_instruction(
  3243. freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  3244. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3245. )
  3246. );
  3247. // check thaw authority
  3248. assert_eq!(
  3249. Err(TokenError::OwnerMismatch.into()),
  3250. do_process_instruction(
  3251. thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
  3252. vec![&mut account_account, &mut mint_account, &mut owner2_account],
  3253. )
  3254. );
  3255. // thaw
  3256. do_process_instruction(
  3257. thaw_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
  3258. vec![&mut account_account, &mut mint_account, &mut owner_account],
  3259. )
  3260. .unwrap();
  3261. let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
  3262. assert_eq!(account.state, AccountState::Initialized);
  3263. }
  3264. }