ui_amount_to_amount.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. mod setup;
  2. use {
  3. crate::setup::mollusk::{create_mint_account, mollusk},
  4. core::str::from_utf8,
  5. mollusk_svm::result::Check,
  6. setup::{mint, TOKEN_PROGRAM_ID},
  7. solana_program_error::ProgramError,
  8. solana_program_test::{tokio, ProgramTest},
  9. solana_pubkey::Pubkey,
  10. solana_signer::Signer,
  11. solana_transaction::Transaction,
  12. };
  13. #[tokio::test]
  14. async fn ui_amount_to_amount() {
  15. let mut context = ProgramTest::new("pinocchio_token_program", TOKEN_PROGRAM_ID, None)
  16. .start_with_context()
  17. .await;
  18. // Given a mint account.
  19. let mint_authority = Pubkey::new_unique();
  20. let freeze_authority = Pubkey::new_unique();
  21. let mint = mint::initialize(
  22. &mut context,
  23. mint_authority,
  24. Some(freeze_authority),
  25. &TOKEN_PROGRAM_ID,
  26. )
  27. .await
  28. .unwrap();
  29. let ui_amount_to_amount_ix = spl_token_interface::instruction::ui_amount_to_amount(
  30. &spl_token_interface::ID,
  31. &mint,
  32. "1000.00",
  33. )
  34. .unwrap();
  35. let tx = Transaction::new_signed_with_payer(
  36. &[ui_amount_to_amount_ix],
  37. Some(&context.payer.pubkey()),
  38. &[&context.payer],
  39. context.last_blockhash,
  40. );
  41. context.banks_client.process_transaction(tx).await.unwrap();
  42. // Then the transaction should succeed.
  43. let account = context.banks_client.get_account(mint).await.unwrap();
  44. assert!(account.is_some());
  45. }
  46. #[test]
  47. fn ui_amount_to_amount_with_maximum_decimals() {
  48. // Given a mint account with `u8::MAX` as decimals.
  49. let mint = Pubkey::new_unique();
  50. let mint_authority = Pubkey::new_unique();
  51. let freeze_authority = Pubkey::new_unique();
  52. let mint_account = create_mint_account(
  53. mint_authority,
  54. Some(freeze_authority),
  55. u8::MAX,
  56. &TOKEN_PROGRAM_ID,
  57. );
  58. // String representing the ui value `0.000....002`
  59. let mut ui_amount = [b'0'; u8::MAX as usize + 1];
  60. ui_amount[1] = b'.';
  61. ui_amount[ui_amount.len() - 1] = b'2';
  62. let input = from_utf8(&ui_amount).unwrap();
  63. // When we convert the ui amount using the mint, the transaction should
  64. // succeed and return 20 as the amount.
  65. let instruction = spl_token_interface::instruction::ui_amount_to_amount(
  66. &spl_token_interface::ID,
  67. &mint,
  68. input,
  69. )
  70. .unwrap();
  71. mollusk().process_and_validate_instruction(
  72. &instruction,
  73. &[(mint, mint_account)],
  74. &[Check::success(), Check::return_data(&20u64.to_le_bytes())],
  75. );
  76. }
  77. #[test]
  78. fn fail_ui_amount_to_amount_with_invalid_ui_amount() {
  79. // Given a mint account with `u8::MAX` as decimals.
  80. let mint = Pubkey::new_unique();
  81. let mint_authority = Pubkey::new_unique();
  82. let freeze_authority = Pubkey::new_unique();
  83. let mint_account = create_mint_account(
  84. mint_authority,
  85. Some(freeze_authority),
  86. u8::MAX,
  87. &TOKEN_PROGRAM_ID,
  88. );
  89. // String representing the ui value `2.0`
  90. let ui_amount = [b'2', b'.', b'0'];
  91. let input = from_utf8(&ui_amount).unwrap();
  92. // When we try to convert the ui amount using the mint, the transaction should
  93. // fail with an error since the resulting value does not fit in an `u64`.
  94. let instruction = spl_token_interface::instruction::ui_amount_to_amount(
  95. &spl_token_interface::ID,
  96. &mint,
  97. input,
  98. )
  99. .unwrap();
  100. mollusk().process_and_validate_instruction(
  101. &instruction,
  102. &[(mint, mint_account)],
  103. &[Check::err(ProgramError::InvalidArgument)],
  104. );
  105. }