diff --git a/contracts/brc21-poc/README.md b/contracts/brc21-poc/README.md index abdeb97b78..9e7762ce53 100644 --- a/contracts/brc21-poc/README.md +++ b/contracts/brc21-poc/README.md @@ -29,3 +29,28 @@ Indexers now accept the Bitcoin-minted BRC21 as minted See the full protocol at https://interlay-labs.gitbook.io/brc-21/ ## Getting started + +### Contracts + +#### Build + +```bash +cd brc21 +cargo contract build +``` + +#### Test + +From inside the `brc21` directory. + +**Run unit tests** + +```bash +cargo test +``` + +**Run integration tests** + +```bash +cargo test --features e2e-tests +``` diff --git a/contracts/brc21-poc/brc21/lib.rs b/contracts/brc21-poc/brc21/lib.rs index 599c090a43..f805066186 100755 --- a/contracts/brc21-poc/brc21/lib.rs +++ b/contracts/brc21-poc/brc21/lib.rs @@ -125,20 +125,127 @@ mod brc21 { /// Imports all the definitions from the outer scope so we can use them here. use super::*; - /// We test if the default constructor does its job. + // Define event types used by this contract + type Event = ::Type; + + const DEFAULT_TICKER: &str = "INTR"; + + fn decode_event (event: &ink::env::test::EmittedEvent) -> Event { + ::decode(&mut &event.data[..]) + .expect("encountered invalid contract event data") + } + + /// Helper function to for mint event tests + fn assert_mint_event( + event: &ink::env::test::EmittedEvent, + ticker: &str, + amount: u128, + account: AccountId, + ) { + let decoded_event = decode_event(event); + match decoded_event { + Event::Mint(mint) => { + assert_eq!(mint.ticker, ticker); + assert_eq!(mint.amount, amount); + assert_eq!(mint.account, account); + }, + _ => panic!("Expected Mint event"), + } + } + + /// Helper function to for redeem event tests + fn assert_redeem_event( + event: &ink::env::test::EmittedEvent, + ticker: &str, + amount: u128, + account: AccountId, + ) { + let decoded_event = decode_event(event); + match decoded_event { + Event::Redeem(redeem) => { + assert_eq!(redeem.ticker, ticker); + assert_eq!(redeem.amount, amount); + assert_eq!(redeem.account, account); + }, + _ => panic!("Expected Redeem event"), + } + } + + /// Test if the default constructor does its job. #[ink::test] - fn default_works() { - let brc21 = Brc21::default(); - assert_eq!(brc21.get(), false); + fn new_works() { + let brc21 = Brc21::new(DEFAULT_TICKER.to_string()); + assert_eq!(brc21.get_ticker(), DEFAULT_TICKER); + assert_eq!(brc21.get_locked(), 0); } - /// We test a simple use case of our contract. + /// Test if minting works #[ink::test] - fn it_works() { - let mut brc21 = Brc21::new(false); - assert_eq!(brc21.get(), false); - brc21.flip(); - assert_eq!(brc21.get(), true); + fn mint_works() { + let mut brc21 = Brc21::new(DEFAULT_TICKER.to_string()); + + // Load the default accounts + let accounts = ink::env::test::default_accounts::(); + + // Alice mints 100 coins + // Default caller is the Alice account 0x01 + brc21.mint(100); + assert_eq!(brc21.get_locked(), 100); + + // Check that the event was emitted + let emitted_events = ink::env::test::recorded_events().collect::>(); + assert_eq!(emitted_events.len(), 1); + assert_mint_event( + &emitted_events[0], + DEFAULT_TICKER, + 100, + AccountId::from([0x01; 32]) // Alice + ); + + // Bob mints 50 coins + ink::env::test::set_caller::(accounts.bob); + brc21.mint(50); + assert_eq!(brc21.get_locked(), 150); + + // Check that the event was emitted + let emitted_events = ink::env::test::recorded_events().collect::>(); + assert_eq!(emitted_events.len(), 2); + assert_mint_event( + &emitted_events[1], + DEFAULT_TICKER, + 50, + AccountId::from([0x02; 32]) // Bob + ); + } + + /// Test if redeeming works + #[ink::test] + fn redeem_works() { + let mut brc21 = Brc21::new(DEFAULT_TICKER.to_string()); + + // Load the default accounts + let accounts = ink::env::test::default_accounts::(); + + // Alice mints 100 coins + // Default caller is the Alice account 0x01 + brc21.mint(100); + assert_eq!(brc21.get_locked(), 100); + + // Bob redeems 50 coins + ink::env::test::set_caller::(accounts.bob); + brc21.redeem(accounts.bob, 50); + assert_eq!(brc21.get_locked(), 50); + + // Check that the event was emitted + let emitted_events = ink::env::test::recorded_events().collect::>(); + assert_eq!(emitted_events.len(), 2); + assert_redeem_event( + &emitted_events[1], + DEFAULT_TICKER, + 50, + AccountId::from([0x02; 32]) // Bob + ); + } }