Skip to content

Commit

Permalink
add method to mint kyc + test (#99)
Browse files Browse the repository at this point in the history
Co-authored-by: Robert Zaremba <[email protected]>
  • Loading branch information
sczembor and robert-zaremba committed Dec 20, 2023
1 parent 5303227 commit 6fd2190
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 4 deletions.
71 changes: 70 additions & 1 deletion contracts/oracle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,53 @@ impl Contract {
Ok(())
}

/// Alows admin to mint KYC soul bound tokens to the provided list of accounts
/// with its respecitve expires_at timestmap.
/// Panics if not admin or the attached deposit is insufficient.
#[payable]
pub fn admin_mint_kyc(
&mut self,
mint_data: Vec<(AccountId, u64)>,
memo: Option<String>,
) -> Promise {
self.assert_admin();

let num_tokens = mint_data.len();
let storage_deposit = mint_deposit(num_tokens);
require!(
env::attached_deposit() >= storage_deposit,
format!(
"Requires attached deposit at least {} yoctoNEAR",
storage_deposit
)
);

let now: u64 = env::block_timestamp_ms();
let mut tokens_metadata: Vec<(AccountId, Vec<TokenMetadata>)> =
Vec::with_capacity(num_tokens);
for (acc, end) in mint_data {
tokens_metadata.push((
acc,
vec![TokenMetadata {
class: CLASS_KYC_SBT,
issued_at: Some(now),
expires_at: Some(end),
reference: None,
reference_hash: None,
}],
));
}

if let Some(memo) = memo {
env::log_str(&format!("SBT mint memo: {}", memo));
}

ext_registry::ext(self.registry.clone())
.with_attached_deposit(storage_deposit)
.with_static_gas(calculate_mint_gas(num_tokens))
.sbt_mint(tokens_metadata)
}

// TODO:
// - fn sbt_renew
}
Expand Down Expand Up @@ -361,7 +408,7 @@ mod checks;
pub mod tests {
use crate::*;
use ed25519_dalek::Keypair;
use near_sdk::test_utils::test_env::alice;
use near_sdk::test_utils::test_env::{alice, bob};
use near_sdk::test_utils::VMContextBuilder;
use near_sdk::{testing_env, VMContext};

Expand Down Expand Up @@ -674,4 +721,26 @@ pub mod tests {
}
assert_eq!(ctr.class_metadata(1).unwrap(), class_metadata());
}

#[test]
#[should_panic(expected = "not an admin")]
fn admin_mint_kyc_not_admin() {
let (_, mut ctr, _) = setup(&alice(), &alice());
let _ = ctr.admin_mint_kyc(vec![(bob(), 100)], None);
}

#[test]
#[should_panic(expected = "Requires attached deposit at least")]
fn admin_mint_kyc_wrong_deposit() {
let (mut ctx, mut ctr, _) = setup(&alice(), &acc_admin());
ctx.attached_deposit = 0;
testing_env!(ctx);
let _ = ctr.admin_mint_kyc(vec![(bob(), 100), (alice(), 100)], None);
}

#[test]
fn admin_mint_kyc() {
let (_, mut ctr, _) = setup(&alice(), &acc_admin());
let _ = ctr.admin_mint_kyc(vec![(bob(), 100), (alice(), 100)], None);
}
}
44 changes: 41 additions & 3 deletions contracts/oracle/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ use sbt::{ClassMetadata, ContractMetadata};
const AUTHORITY_KEY: &str = "zqMwV9fTRoBOLXwt1mHxBAF3d0Rh9E9xwSAXR3/KL5E=";
const CLAIM_TTL: u64 = 3600 * 24 * 365 * 100;

async fn init(worker: &Worker<impl DevNetwork>) -> anyhow::Result<(Contract, Account, Account)> {
async fn init(
worker: &Worker<impl DevNetwork>,
) -> anyhow::Result<(Contract, Contract, Account, Account, Account)> {
// deploy contracts
let registry = worker.dev_deploy(include_bytes!("../../res/registry.wasm"));

let registry = registry.await?;

let alice = worker.dev_create_account().await?;
let bob = worker.dev_create_account().await?;
let admin = worker.dev_create_account().await?;
let auth_flagger = worker.dev_create_account().await?;

Expand Down Expand Up @@ -56,13 +59,13 @@ async fn init(worker: &Worker<impl DevNetwork>) -> anyhow::Result<(Contract, Acc
// let block = worker.view_block().await?;
// let now = block.timestamp() / MSECOND; // timestamp in seconds

Ok((oracle.to_owned(), admin, alice))
Ok((oracle.to_owned(), registry.to_owned(), admin, alice, bob))
}

#[tokio::test]
async fn check_arithmetic_exception_dev() -> anyhow::Result<()> {
let worker = near_workspaces::sandbox().await?;
let (oracle, _, alice) = init(&worker).await?;
let (oracle, _, _, alice, _) = init(&worker).await?;
check_arithmetic_exception(oracle, alice).await?;

Ok(())
Expand Down Expand Up @@ -222,6 +225,41 @@ async fn test_mint_sbt() -> anyhow::Result<()> {
Ok(())
}

#[tokio::test]
async fn test_admin_mint_kyc() -> anyhow::Result<()> {
let worker = near_workspaces::sandbox().await?;
let (oracle, registry, admin, alice, bob) = init(&worker).await?;

// get current block time
let block = worker.view_block().await?;
let one_day_in_milliseconds: u64 = 24 * 60 * 60 * 1000;
let now = block.timestamp() / 1_000_000; // timestamp in miliseconds
let expires_at = now + one_day_in_milliseconds;

let mint_data = vec![(alice.id(), expires_at), (bob.id(), expires_at)];

let res = admin
.call(oracle.id(), "admin_mint_kyc")
.args_json(json!({"mint_data":mint_data, "memo": "kyc_test"}))
.deposit(2 * MINT_TOTAL_COST)
.max_gas()
.transact()
.await?;
assert!(res.is_success(), "{:?}", res.receipt_failures());

let res: u64 = admin
.call(registry.id(), "sbt_supply_by_class")
.args_json(json!({"issuer":oracle.id(), "class": 2}))
.max_gas()
.transact()
.await?
.json()?;

assert_eq!(res, 2);

Ok(())
}

async fn check_arithmetic_exception(oracle: Contract, alice: Account) -> anyhow::Result<()> {
//
// replicating claim_sig_and_sbt_mint unit test
Expand Down

0 comments on commit 6fd2190

Please sign in to comment.