Skip to content

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
DOBEN committed Nov 28, 2023
1 parent b012b70 commit 17e8ee7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 24 deletions.
57 changes: 37 additions & 20 deletions examples/cis2-multi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ const SUPPORTS_PERMIT_ENTRYPOINTS: [EntrypointName; 2] =
/// Tag for the CIS3 Nonce event.
pub const NONCE_EVENT_TAG: u8 = u8::MAX - 5;

/// The amount of tokens to airdrop when the mint function is invoked.
pub const MINT_AIRDROP: TokenAmountU64 = TokenAmountU64(100);

/// Tagged events to be serialized for the event log.
#[derive(Debug, Serial, Deserial, PartialEq, Eq)]
#[concordium(repr(u8))]
Expand All @@ -104,8 +101,11 @@ pub struct NonceEvent {
pub nonce: u64,
}

// Implementing a custom schemaType to the `Event` combining all CIS2/CIS3
// events.
// Implementing a custom schemaType for the `Event` struct containing all
// CIS2/CIS3 events. This custom implementation flattens the fields to avoid one
// level of nesting. Deriving the schemaType would result in e.g.: {"Nonce":
// [{...fields}] }. In contrast, this custom schemaType implementation results
// in e.g.: {"Nonce": {...fields} }
impl schema::SchemaType for Event {
fn get_type() -> schema::Type {
let mut event_map = BTreeMap::new();
Expand Down Expand Up @@ -194,8 +194,7 @@ pub type ContractTokenAmount = TokenAmountU64;
pub struct MintParams {
/// Owner of the newly minted tokens.
pub owner: Address,
/// The metadata_url of the token (is ignored except for the first time
/// a token_id is minted).
/// The metadata_url of the token.
pub metadata_url: MetadataUrl,
/// The token_id to mint/create additional tokens.
pub token_id: ContractTokenId,
Expand Down Expand Up @@ -241,6 +240,8 @@ struct State<S = StateApi> {
/// mapping keeps track of the next nonce that needs to be used by the
/// account to generate a signature.
nonces_registry: StateMap<AccountAddress, u64, S>,
/// The amount of tokens airdropped when the mint function is invoked.
mint_airdrop: TokenAmountU64,
}
/// The parameter type for the contract function `supportsPermit`.
#[derive(Debug, Serialize, SchemaType)]
Expand Down Expand Up @@ -370,12 +371,13 @@ impl From<CustomContractError> for ContractError {

impl State {
/// Construct a state with no tokens
fn empty(state_builder: &mut StateBuilder) -> Self {
fn empty(state_builder: &mut StateBuilder, mint_airdrop: TokenAmountU64) -> Self {
State {
state: state_builder.new_map(),
tokens: state_builder.new_map(),
implementors: state_builder.new_map(),
state: state_builder.new_map(),
tokens: state_builder.new_map(),
implementors: state_builder.new_map(),
nonces_registry: state_builder.new_map(),
mint_airdrop,
}
}

Expand All @@ -388,6 +390,7 @@ impl State {
token_id: &ContractTokenId,
metadata_url: &MetadataUrl,
owner: &Address,
mint_airdrop: TokenAmountU64,
state_builder: &mut StateBuilder,
) -> MetadataUrl {
let token_metadata = self.tokens.get(token_id).map(|x| x.to_owned());
Expand All @@ -398,7 +401,7 @@ impl State {
let mut owner_state =
self.state.entry(*owner).or_insert_with(|| AddressState::empty(state_builder));
let mut owner_balance = owner_state.balances.entry(*token_id).or_insert(0.into());
*owner_balance += MINT_AIRDROP;
*owner_balance += mint_airdrop;

if let Some(token_metadata) = token_metadata {
token_metadata
Expand Down Expand Up @@ -518,10 +521,17 @@ impl State {
// Contract functions

/// Initialize contract instance with no token types.
#[init(contract = "cis2_multi", event = "Cis2Event<ContractTokenId, ContractTokenAmount>")]
fn contract_init(_ctx: &InitContext, state_builder: &mut StateBuilder) -> InitResult<State> {
#[init(
contract = "cis2_multi",
event = "Cis2Event<ContractTokenId, ContractTokenAmount>",
parameter = "TokenAmountU64"
)]
fn contract_init(ctx: &InitContext, state_builder: &mut StateBuilder) -> InitResult<State> {
// Parse the parameter.
let mint_airdrop: TokenAmountU64 = ctx.parameter_cursor().get()?;

// Construct the initial contract state.
Ok(State::empty(state_builder))
Ok(State::empty(state_builder, mint_airdrop))
}

#[derive(Serialize, SchemaType, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -599,12 +609,18 @@ fn contract_mint(

let (state, builder) = host.state_and_builder();
// Mint the token in the state.
let token_metadata = state.mint(&params.token_id, &params.metadata_url, &params.owner, builder);
let token_metadata = state.mint(
&params.token_id,
&params.metadata_url,
&params.owner,
state.mint_airdrop,
builder,
);

// Event for minted token.
logger.log(&Cis2Event::Mint(MintEvent {
token_id: params.token_id,
amount: MINT_AIRDROP,
amount: state.mint_airdrop,
owner: params.owner,
}))?;

Expand Down Expand Up @@ -686,14 +702,15 @@ fn contract_transfer(
// Get the sender who invoked this contract function.
let sender = ctx.sender();

for transer in transfers {
for transfer_entry in transfers {
// Authenticate the sender for this transfer
ensure!(
transer.from == sender || host.state().is_operator(&sender, &transer.from),
transfer_entry.from == sender
|| host.state().is_operator(&sender, &transfer_entry.from),
ContractError::Unauthorized
);

transfer(transer, host, logger)?;
transfer(transfer_entry, host, logger)?;
}
Ok(())
}
Expand Down
3 changes: 2 additions & 1 deletion examples/cis2-multi/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,8 @@ fn initialize_chain_and_contract() -> (Chain, AccountKeys, ContractAddress) {
amount: Amount::zero(),
mod_ref: deployment.module_reference,
init_name: OwnedContractName::new_unchecked("init_cis2_multi".to_string()),
param: OwnedParameter::empty(),
param: OwnedParameter::from_serial(&TokenAmountU64(100))
.expect("UpdateOperator params"),
})
.expect("Initialize contract");

Expand Down
7 changes: 4 additions & 3 deletions examples/cis3-nft-sponsored-txs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,14 +691,15 @@ fn contract_transfer(
// Get the sender who invoked this contract function.
let sender = ctx.sender();

for transer in transfers {
for transfer_entry in transfers {
// Authenticate the sender for this transfer
ensure!(
transer.from == sender || host.state().is_operator(&sender, &transer.from),
transfer_entry.from == sender
|| host.state().is_operator(&sender, &transfer_entry.from),
ContractError::Unauthorized
);

transfer(transer, host, logger)?;
transfer(transfer_entry, host, logger)?;
}
Ok(())
}
Expand Down

0 comments on commit 17e8ee7

Please sign in to comment.