-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CEP-78 #410
CEP-78 #410
Conversation
WalkthroughThe recent updates focus on enhancing functionality and efficiency in dictionary operations, enhancing the CEP-78 NFT contract capabilities, and refining the contract environment setup. Key changes include the use of byte slices for dictionary keys, new contract declarations, and updated event handling. Additionally, Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
@@ -49,7 +49,7 @@ pub trait ContractContext { | |||
/// | |||
/// * `dictionary_name` - The name of the dictionary. | |||
/// * `key` - The key to retrieve the value for. | |||
fn get_dictionary_value(&self, dictionary_name: &str, key: &str) -> Option<Bytes>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure this works by running a livenet example of cep-18 against original contract implementation.
@@ -58,7 +58,7 @@ pub trait ContractContext { | |||
/// * `dictionary_name` - The name of the dictionary. | |||
/// * `key` - The key to set the value for. | |||
/// * `value` - The value to set. | |||
fn set_dictionary_value(&self, dictionary_name: &str, key: &str, value: CLValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why only changed in dictionaries, what about named keys?
Benchmark report
|
Benchmark report
|
Benchmark report
|
Benchmark report
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 32
Out of diff range and nitpick comments (12)
odra-vm/src/odra_vm_contract_env.rs (1)
36-46
: Consider adding documentation to these dictionary-related methods to clarify their functionalities and expected behaviors.odra-casper/wasm-env/src/wasm_contract_env.rs (1)
33-43
: Consider adding documentation to these dictionary-related methods to clarify their functionalities and expected behaviors.modules/src/cep78/settings.rs (1)
8-45
: Consider adding documentation to these storage definitions to clarify their purposes and the expected error handling.modules/src/cep78/reverse_lookup.rs (1)
141-158
: Add missing implementation details inon_mint
.The
on_mint
method contains a TODO comment indicating missing implementation details. It's important to address these to ensure the method functions as expected.modules/src/cep78/metadata.rs (1)
18-23
: Consider adding documentation for thesingle_value_storage!
macro usage.It would be beneficial for maintainability to include comments explaining the purpose and usage of this macro, especially since it's used multiple times with different parameters.
modules/src/cep78/modalities.rs (2)
9-15
: Ensure documentation forWhitelistMode
enum.It would be beneficial to add comprehensive documentation for the
WhitelistMode
enum to explain its purpose and usage within the system, especially since it controls critical functionality.
29-37
: Review default behavior and documentation forNFTHolderMode
.The default behavior for
NFTHolderMode
is set toMixed
, but this is not clearly documented. Adding explicit documentation about the default behavior and its implications would improve code clarity and maintainability.modules/src/cep78/tests/mint.rs (2)
65-66
: Consider removing or updating the ignored test to reflect current project requirements.This test is marked as ignored with a comment about the proxy pattern. If this pattern is no longer relevant, consider updating or removing the test to keep the test suite clean and relevant.
164-172
: Consider implementing or removing commented-out code.There is a block of commented-out code related to reverse lookup. If this feature is not planned for immediate implementation, consider removing the code or adding a TODO with a clear timeline or conditions for implementation.
modules/src/cep78/token.rs (1)
30-34
: Consider using a more descriptive name for thesingle_value_storage!
macro.While the macro usage is correct, the name
Cep78TransferFilterContract
could be more descriptive regarding its purpose in the context of the CEP-78 standard. Consider renaming it to reflect its specific role or functionality.modules/src/cep78/tests/transfer.rs (2)
595-623
: Note the missing implementation for tracking page table entries.The actual implementation for tracking page table entries during token transfers is marked as TODO and not implemented yet. It's important to address this in future updates.
626-652
: Note the missing implementation for transfers to unregistered owners.The actual implementation for preventing transfers to unregistered owners is marked as TODO and not implemented yet. It's important to address this in future updates.
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (1)
.DS_Store
is excluded by!**/.DS_Store
Files selected for processing (45)
- .gitignore (1 hunks)
- benchmark/src/storage.rs (1 hunks)
- core/src/args.rs (2 hunks)
- core/src/contract_container.rs (3 hunks)
- core/src/contract_context.rs (2 hunks)
- core/src/contract_env.rs (3 hunks)
- modules/Cargo.toml (1 hunks)
- modules/Odra.toml (1 hunks)
- modules/src/cep18/storage.rs (3 hunks)
- modules/src/cep78/constants.rs (1 hunks)
- modules/src/cep78/data.rs (1 hunks)
- modules/src/cep78/error.rs (1 hunks)
- modules/src/cep78/events.rs (1 hunks)
- modules/src/cep78/metadata.rs (1 hunks)
- modules/src/cep78/mod.rs (1 hunks)
- modules/src/cep78/modalities.rs (1 hunks)
- modules/src/cep78/reverse_lookup.rs (1 hunks)
- modules/src/cep78/settings.rs (1 hunks)
- modules/src/cep78/tests/acl.rs (1 hunks)
- modules/src/cep78/tests/burn.rs (1 hunks)
- modules/src/cep78/tests/costs.rs (1 hunks)
- modules/src/cep78/tests/events.rs (1 hunks)
- modules/src/cep78/tests/installer.rs (1 hunks)
- modules/src/cep78/tests/metadata.rs (1 hunks)
- modules/src/cep78/tests/mint.rs (1 hunks)
- modules/src/cep78/tests/mod.rs (1 hunks)
- modules/src/cep78/tests/set_variables.rs (1 hunks)
- modules/src/cep78/tests/transfer.rs (1 hunks)
- modules/src/cep78/tests/utils.rs (1 hunks)
- modules/src/cep78/token.rs (1 hunks)
- modules/src/cep78/utils.rs (1 hunks)
- modules/src/cep78/whitelist.rs (1 hunks)
- modules/src/lib.rs (2 hunks)
- modules/src/storage.rs (1 hunks)
- odra-casper/livenet-env/src/livenet_contract_env.rs (1 hunks)
- odra-casper/rpc-client/src/casper_client.rs (1 hunks)
- odra-casper/wasm-env/src/host_functions.rs (3 hunks)
- odra-casper/wasm-env/src/wasm_contract_env.rs (1 hunks)
- odra-schema/src/custom_type.rs (2 hunks)
- odra-schema/src/ty.rs (2 hunks)
- odra-vm/src/odra_vm_contract_env.rs (1 hunks)
- odra-vm/src/vm/odra_vm.rs (3 hunks)
- odra-vm/src/vm/odra_vm_state.rs (1 hunks)
- odra-vm/src/vm/storage.rs (6 hunks)
- odra/src/lib.rs (1 hunks)
Files not summarized due to errors (1)
- odra-vm/src/odra_vm_contract_env.rs: Error: Server error. Please try again later.
Files not reviewed due to errors (2)
- modules/src/cep78/tests/costs.rs (no review received)
- odra-casper/wasm-env/src/host_functions.rs (no review received)
Files skipped from review due to trivial changes (3)
- .gitignore
- modules/src/cep78/constants.rs
- odra/src/lib.rs
Additional comments not posted (107)
modules/src/cep78/mod.rs (1)
3-15
: All module declarations appear to be correctly structured and consistent with Rust's module system.modules/src/lib.rs (2)
4-4
: The recursion limit has been set to "256". Ensure this is sufficient for the complexity of the macros used in this project.
11-11
: Thecep78
module has been correctly declared and is consistent with the project's structure.modules/Odra.toml (1)
25-36
: New contract declarations forcep78
have been added correctly and are consistent with the project's structure.benchmark/src/storage.rs (2)
41-41
: The methodset_dictionary_value
has been updated to use byte slices for keys, aligning with the project's performance optimization goals.
47-47
: The methodget_dictionary_value
has been updated to use byte slices for keys. Ensure that all calls to this method across the project have been updated accordingly.Verification successful
The output from the executed script indicates that all instances of
get_dictionary_value
across various files in the codebase are using byte slices for keys, as required by the updated method signature. Each call toget_dictionary_value
correctly passes a byte slice (&[u8]
) as the key parameter. This confirms that the necessary updates have been made consistently across the project.Conclusion:
The verification confirms that all calls toget_dictionary_value
in the project have been correctly updated to use byte slices for keys. There are no instances where the old signature is used.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all calls to `get_dictionary_value` use byte slices for keys. # Test: Search for the function usage with old signature. Expect: No occurrences. rg --type rust $'get_dictionary_value\\([^,]+, [^&]'Length of output: 1382
modules/Cargo.toml (1)
14-23
: New dependencies (serde
,serde_json
,serde-json-wasm
,base16
,once_cell
, andblake2
) have been added correctly. Ensure that these dependencies are necessary for the project's functionality and check for potential version conflicts.modules/src/cep78/tests/set_variables.rs (2)
11-39
: The unit testonly_installer_should_be_able_to_toggle_allow_minting
is well-structured and covers the scenario adequately. Ensure that the error handling and event emission are correctly implemented.
50-64
: The unit testinstaller_should_be_able_to_toggle_operator_burn_mode
correctly tests the functionality. Ensure that the event emission is correctly implemented and matches the expected format.modules/src/cep78/tests/mod.rs (2)
25-31
: The utility functiondefault_args_builder
is correctly implemented and provides a clear, reusable way to build default arguments for tests.
33-38
: The static variableTEST_CUSTOM_METADATA
is correctly implemented usingLazy
for efficient initialization. Ensure that the data it contains is accurate and relevant to the tests.modules/src/cep78/whitelist.rs (2)
25-28
: The methodclear
inCep78ACLWhitelist
correctly implements the functionality to clear the ACL whitelist. Ensure that this method is called appropriately within the system to maintain correct state management.
62-75
: The methodupdate
inACLWhitelist
handles the updating of whitelist entries based on the mode. Ensure that the error handling (InvalidWhitelistMode
) is correctly triggered under the appropriate conditions.modules/src/cep78/tests/utils.rs (2)
48-63
: LGTM! Efficient use offilter_map
to retrieve specific gas costs.
65-74
: LGTM! Consistent and efficient retrieval of deployment gas costs.modules/src/cep78/tests/events.rs (1)
59-82
: LGTM! Proper setup and validation of conditions in the test for no event recording.modules/src/cep78/events.rs (7)
3-18
: LGTM! Well-defined event structure and constructor forMint
.
21-35
: LGTM! Consistent event structure and constructor forBurn
.
37-52
: LGTM! Consistent event structure and constructor forApproval
.
54-64
: LGTM! Consistent event structure and constructor forApprovalRevoked
.
66-76
: LGTM! Consistent event structure and constructor forApprovalForAll
.
78-88
: LGTM! Consistent event structure and constructor forRevokedForAll
.
90-112
: LGTM! Well-defined event structure and constructor forTransfer
, including appropriate handling of optional fields.odra-vm/src/odra_vm_contract_env.rs (2)
36-46
: LGTM! Correct implementation of dictionary operations in the VM environment.
36-46
: LGTM! Correct implementation of various contract-related functionalities in the VM environment.odra-casper/wasm-env/src/wasm_contract_env.rs (3)
33-43
: LGTM! Correct implementation of dictionary operations in the Wasm environment.
33-43
: LGTM! Correct delegation of hashing operation to host functions in the Wasm environment.
33-43
: LGTM! Correct implementation of various contract-related functionalities in the Wasm environment.modules/src/cep78/settings.rs (2)
8-45
: LGTM! Correct use ofsingle_value_storage
macro for defining various settings with appropriate error handling.
59-130
: LGTM! Well-implemented methods for managing settings with clear interfaces and optimized performance.odra-schema/src/custom_type.rs (2)
54-54
: Addition ofBytes
to schema custom types is appropriate for handling byte arrays.
55-55
: Inclusion ofURef
in schema custom types is crucial for referencing blockchain data.core/src/contract_context.rs (3)
52-52
: Update to accept byte slices as dictionary keys aligns with performance optimization efforts.Verification successful
The verification of the
get_dictionary_value
method's integration with existing contracts has been successfully completed. All occurrences in the codebase use byte slices for keys, consistent with the updated method signature. This confirms that the method's update aligns with the project's performance optimization efforts and has been correctly integrated across various components of the system.
- Files and locations verified:
odra-vm/src/odra_vm_contract_env.rs
odra-casper/wasm-env/src/wasm_contract_env.rs
odra-casper/wasm-env/src/host_functions.rs
odra-casper/rpc-client/src/casper_client.rs
odra-casper/livenet-env/src/livenet_contract_env.rs
modules/src/storage.rs
modules/src/cep78/tests/transfer.rs
modules/src/cep78/metadata.rs
modules/src/cep18/storage.rs
core/src/contract_env.rs
benchmark/src/storage.rs
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify integration of `get_dictionary_value` with existing contracts. # Test: Search for the function usage. Expect: Only occurances with byte slice keys. rg --type rust $'get_dictionary_value'Length of output: 1974
61-61
: Update to accept byte slices as dictionary keys inset_dictionary_value
is consistent with performance optimization efforts.Verification successful
The verification process confirms that the updated
set_dictionary_value
method is correctly integrated across the codebase. All instances use byte slices for dictionary keys, including the usage wherekey
is derived from thecompound_key
function, which returns a byte array that is compatible as a byte slice.
- odra-vm/src/odra_vm_contract_env.rs
- odra-casper/wasm-env/src/wasm_contract_env.rs
- odra-casper/wasm-env/src/host_functions.rs
- odra-casper/livenet-env/src/livenet_contract_env.rs
- modules/src/storage.rs
- modules/src/cep78/metadata.rs
- modules/src/cep18/storage.rs
- benchmark/src/storage.rs
- core/src/contract_env.rs
- core/src/contract_context.rs
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify integration of `set_dictionary_value` with existing contracts. # Test: Search for the function usage. Expect: Only occurances with byte slice keys. rg --type rust $'set_dictionary_value'Length of output: 1715
Script:
#!/bin/bash # Description: Verify the type of `key` in the suspicious usage of `set_dictionary_value`. # Test: Check the type of `key` in the specific file where it's used directly. rg --type rust 'let key =' modules/src/storage.rsLength of output: 193
Script:
#!/bin/bash # Description: Verify the return type of `compound_key` used in defining `key`. # Test: Search for the definition of `compound_key` to determine its return type. rg --type rust 'fn compound_key' modules/src/storage.rsLength of output: 157
63-67
: Addition ofremove_dictionary
method enhances storage management capabilities.Verification successful
The verification of the
remove_dictionary
method's integration across the project shows that it is implemented and used consistently in various parts of the codebase. This includes multiple contract environments and direct usage within contract logic, indicating a successful integration.
livenet_contract_env.rs
,wasm_contract_env.rs
,odra_vm_contract_env.rs
: Implementations in different environments.host_functions.rs
,odra_vm_state.rs
: Core functionality implementations.whitelist.rs
: Usage in contract logic.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify integration of `remove_dictionary` with existing contracts. # Test: Search for the function usage. Expect: Proper usage across the project. rg --type rust $'remove_dictionary'Length of output: 1254
odra-casper/livenet-env/src/livenet_contract_env.rs (3)
42-42
: Update to handle byte slices inget_dictionary_value
aligns with project standards and the error handling is crucial for live network environments.
50-50
: Update to handle byte slices inset_dictionary_value
aligns with project standards and the error handling is crucial for live network environments.
54-57
: Addition ofremove_dictionary
with error handling to prevent execution without a deploy is crucial for maintaining state integrity in live network environments.modules/src/storage.rs (5)
1-23
: Update tosingle_value_storage
macro to include error handling enhances user feedback and error management.
39-59
: Update tokey_value_storage
macro to handle dictionary keys as byte slices aligns with performance optimization efforts.
61-93
: Addition ofbase64_encoded_key_value_storage
macro extends key-value storage capabilities to handle non-ASCII or binary data, enhancing flexibility.
95-134
: Addition ofcompound_key_value_storage
macro allows for handling complex data structures with compound keys, enhancing data modeling capabilities.
136-146
:compound_key
function uses the environment's hash function to ensure consistent key handling, crucial for the integrity of compound key operations.odra-schema/src/ty.rs (1)
162-166
: Inclusion ofContractHash
as aNamedCLType
is essential for representing contract hashes in type-safe operations.modules/src/cep78/data.rs (4)
28-36
: Addition ofadd
method toCep78TokenCounter
enhances token management by allowing dynamic increments of the minted tokens count.
65-85
:init
method inCollectionData
properly sets up initial state with checks against zero or excessive token supply, crucial for maintaining token system integrity.
117-137
: Methods for managing token ownership, issuance, and counts inCollectionData
are well-implemented, covering essential functionalities with necessary checks and balances.
150-157
:mark_burnt
andis_burnt
methods provide essential management of token burning status, aligning with token lifecycle needs.core/src/args.rs (1)
39-45
: Addition ofunwrap_or
method toMaybe
enum enhances handling of optional values by providing a flexible, error-tolerant way to unwrap.modules/src/cep78/error.rs (1)
1-173
: Comprehensive error definitions inCEP78Error
are crucial for robust error handling and user feedback in CEP-78 operations.modules/src/cep18/storage.rs (2)
129-129
: Ensure consistent error handling forget_dictionary_value
.Verification successful
Consistent Error Handling for
get_dictionary_value
VerifiedThe review of the
get_dictionary_value
function across various modules and files in the codebase shows a consistent pattern in error handling. The function typically returns anOption<Bytes>
, and the handling of this optional value is consistent, primarily using methods likeunwrap_or_default()
or similar error-resilient methods. This ensures that the function's usage does not lead to unhandled exceptions or panics due to missing values.Here are some key observations from the codebase:
- In
modules/src/storage.rs
, the function is used withunwrap_or_default()
, which provides a default value in case ofNone
.- In
modules/src/cep18/storage.rs
, the function is also used withunwrap_or_default()
for bothBALANCES_KEY
andALLOWANCES_KEY
.- In
modules/src/cep78/metadata.rs
, it usesunwrap_or_revert_with()
, which is another form of error handling that ensures errors are managed explicitly.These usages confirm that the error handling around
get_dictionary_value
is handled appropriately and consistently across the project.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify consistent error handling for `get_dictionary_value` across the project. # Test: Search for the function usage. Expect: Consistent error handling. rg --type rust $'get_dictionary_value'Length of output: 1974
Script:
#!/bin/bash # Description: Further investigate how the returned Option<Bytes> from get_dictionary_value is handled in each case. # Test: Search for the handling of the function's return value in each file where it's used. rg --type rust -C 3 $'get_dictionary_value'Length of output: 7973
171-171
: Ensure consistent error handling forset_dictionary_value
in allowances context.Verification successful
The examination of the
set_dictionary_value
usage in both the allowances and balances contexts within themodules/src/cep18/storage.rs
file reveals a consistent approach. Both usages directly invoke the function without any surrounding explicit error handling mechanisms. This suggests that error handling is either managed internally within the function or by the environment's error handling mechanisms, consistently across different contexts.
- Allowances Context: Direct setting of allowances without explicit error handling.
- Balances Context: Direct setting of balances without explicit error handling.
Given this consistency, the error handling for
set_dictionary_value
in the allowances context appears to be in line with other usages within the same module.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify consistent error handling for `set_dictionary_value` in allowances context across the project. # Test: Search for the function usage. Expect: Consistent error handling. rg --type rust $'set_dictionary_value'Length of output: 1715
Script:
#!/bin/bash # Description: Inspect error handling around `set_dictionary_value` usage in allowances context. # Search for error handling mechanisms around the usage of `set_dictionary_value` in the allowances context. rg --type rust -C 5 "set_dictionary_value\(.*ALLOWANCES_KEY" modules/src/cep18/storage.rsLength of output: 539
Script:
#!/bin/bash # Description: Inspect error handling around `set_dictionary_value` usage in balances context for comparison. # Search for error handling mechanisms around the usage of `set_dictionary_value` in the balances context. rg --type rust -C 5 "set_dictionary_value\(.*BALANCES_KEY" modules/src/cep18/storage.rsLength of output: 480
modules/src/cep78/tests/installer.rs (1)
107-112
: Verify that the error handling for re-burning a previously burnt token is consistent across the project.core/src/contract_env.rs (1)
107-110
: Ensure consistent error handling forget_dictionary_value
.Verification successful
Based on the search results, the function
get_dictionary_value
is used across multiple files and modules in the project. Most of these usages return anOption<Bytes>
, which suggests a pattern of using Rust's option type for error handling—returningNone
in case of an error. However, to ensure that error handling is indeed consistent (e.g., no unhandled errors, no unnecessary error logs, or deviations in error handling strategy), a deeper examination of each usage context is necessary.To proceed, I will generate additional verification scripts to inspect the implementation and usage of
get_dictionary_value
in a few key files to confirm the consistency of error handling.
The examination of the
get_dictionary_value
function across different files in the project reveals a consistent pattern of error handling. The function typically returns anOption<Bytes>
, whereNone
is returned in case of an error, such as when a value is not found. This pattern is observed across various implementations in different environments, such as wasm-env, rpc-client, and core.In the detailed implementations, errors are handled by reverting the operation or returning
None
, without any unhandled exceptions or inconsistent error handling mechanisms. This confirms that the error handling for theget_dictionary_value
function is consistent across the project.Therefore, the review comment regarding ensuring consistent error handling for
get_dictionary_value
has been verified and found to be correctly implemented across the codebase.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify consistent error handling for `get_dictionary_value` across the project. # Test: Search for the function usage. Expect: Consistent error handling. rg --type rust $'get_dictionary_value'Length of output: 1974
Script:
#!/bin/bash # Inspect error handling in wasm-env cat odra-casper/wasm-env/src/wasm_contract_env.rs cat odra-casper/wasm-env/src/host_functions.rs # Inspect error handling in rpc-client cat odra-casper/rpc-client/src/casper_client.rs # Inspect error handling in core environment cat core/src/contract_env.rsLength of output: 66677
modules/src/cep78/utils.rs (1)
76-80
: Check for potential data races inburn
method.The
burn
method accesses shared state (nft_contract
) which might lead to data races in a concurrent environment. Verify that appropriate locking mechanisms are used.odra-vm/src/vm/storage.rs (1)
76-86
: Validate inputs inremove_dict
to prevent potential errors.The
remove_dict
method removes a dictionary without validating the existence of the dictionary key. Consider adding checks to prevent errors in case the key does not exist.Verification successful
The review comment regarding the lack of input validation in the
remove_dict
method is accurate. The method currently removes a dictionary key without checking its existence, which could lead to potential errors if the key does not exist. It is advisable to implement checks to ensure the dictionary key exists before attempting to remove it.
- File:
odra-vm/src/vm/storage.rs
- Method:
remove_dict
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for input validation in remove_dict method. # Test: Search for validation patterns. Expect: Validation code before removing dictionary. rg --type rust 'remove_dict' odra-vm/src/vm/storage.rsLength of output: 226
modules/src/cep78/metadata.rs (3)
55-66
: Ensure proper error handling for dictionary operations.
98-104
: Validate JSON schema parsing error handling.Verification successful
The JSON schema parsing error handling has been verified across two occurrences in the codebase. Both instances correctly handle errors by reverting the operation with
CEP78Error::InvalidJsonSchema
, ensuring that contract installation fails as expected upon encountering a parsing error. This aligns with the requirements specified in the review comment.
- First occurrence:
modules/src/cep78/metadata.rs
around line 102- Second occurrence:
modules/src/cep78/metadata.rs
around line 106Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Ensure that JSON schema parsing errors are correctly handled and lead to contract installation failure. # Test: Search for JSON schema parsing in contract installation. Expect: Correct error handling. rg --type rust $'serde_json_wasm::from_str::<CustomMetadataSchema>'Length of output: 299
Script:
#!/bin/bash # Description: Verify the error handling for the second occurrence of JSON schema parsing. # Focus: Check if the error leads to a contract installation failure. # Extract the surrounding code for the second occurrence of JSON schema parsing. rg --type rust -C 5 'serde_json_wasm::from_str::<CustomMetadataSchema>\(&self.json_schema.get\(\)\)' modules/src/cep78/metadata.rsLength of output: 525
241-307
: Check the implementation ofget_metadata_schema
.Verification successful
The provided shell script output shows two occurrences of the
get_metadata_schema
method within themetadata.rs
file. One is the definition of the method itself, and the other is its usage where atoken_schema
is being retrieved. This aligns with the expected behavior of the method being used within its module.However, the script was intended to verify the correct implementation and error handling within the
get_metadata_schema
method. The output does not provide detailed insights into how error handling is implemented, particularly in theCustomValidated
case where JSON parsing errors are supposed to revert the operation.To further verify the error handling, particularly how the method handles potential errors in the
CustomValidated
case, we need to inspect the error handling logic more closely. This involves checking how errors from theserde_json_wasm::from_str
function are managed and ensuring that they correctly trigger therevert
operation with the appropriate environment.Given the current information, we need to delve deeper into the error handling specifics of the
CustomValidated
case.
The new script output provides detailed context around the error handling in the
CustomValidated
case of theget_metadata_schema
method. It shows that the method attempts to parse a JSON string into aCustomMetadataSchema
object. If parsing fails, it triggers an error (CEP78Error::InvalidJsonSchema
) and reverts the operation usingunwrap_or_revert
with the environment provided byself.env()
.This error handling mechanism is crucial for ensuring that only valid JSON schemas are processed, and any invalid schemas result in a controlled failure, preventing further execution with potentially corrupted data.
Given this detailed insight into the error handling logic, it appears that the implementation of
get_metadata_schema
in theCustomValidated
case is correctly handling errors as expected. The method properly manages JSON parsing errors and ensures that operations are reverted in case of an error, which aligns with robust error handling practices in critical operations like schema validation.Based on this information, the implementation of the
get_metadata_schema
method, particularly its error handling, is verified to be correct.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the correct implementation of `get_metadata_schema` method, especially the error handling and schema retrieval logic. # Test: Search for the usage of `get_metadata_schema`. Expect: Correct implementation and error handling. rg --type rust $'get_metadata_schema'Length of output: 239
Script:
#!/bin/bash # Description: Verify the error handling in the `CustomValidated` case of the `get_metadata_schema` method. # Test: Search for the error handling logic in the `CustomValidated` case. rg --type rust --context 5 'CustomValidated' modules/src/cep78/metadata.rsLength of output: 2184
modules/src/cep78/tests/acl.rs (5)
17-33
: Ensure comprehensive testing for ACL whitelist functionality.Verification successful
The review comment regarding the comprehensive testing of ACL whitelist functionality appears to be addressed adequately. The codebase demonstrates extensive use of the
acl_white_list
across various test files, covering different scenarios and types of whitelists (contract, account, mixed). This suggests a thorough approach to testing the ACL whitelist functionality in different contexts.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the ACL whitelist functionality is comprehensively tested, especially the scenarios involving locked and unlocked modes. # Test: Search for tests covering ACL whitelist scenarios. Expect: Comprehensive coverage. rg --type rust $'acl_white_list'Length of output: 2234
39-58
: Check error handling in minting mode validation.Verification successful
The review comment requested verification of the error handling for the minting mode validation when an ACL whitelist is provided. The script executed searched for occurrences of
InvalidMintingMode
in the Rust files of the codebase.Analysis of Script Results:
- The error
InvalidMintingMode
is referenced in several files:
token.rs
: The error is used in a method to revert an operation.acl.rs
: The error is correctly used in the test to check the robustness of the error handling.modalities.rs
: The error is returned in some conditional logic.error.rs
: The error is defined here with a specific error code.Conclusion:
The error handling for the minting mode validation appears to be implemented across multiple files and is used consistently in the context of ACL whitelist provision. The test in
acl.rs
specifically checks for this error when the minting mode is not set correctly, aligning with the intended functionality described in the review comment.Given the evidence from the script output, the error handling for the minting mode validation when an ACL whitelist is provided seems robust and correctly implemented.
Error Handling in Minting Mode Validation Verified
- The error
InvalidMintingMode
is appropriately triggered and handled in the test scenario provided inacl.rs
.- The usage of this error across the codebase supports its robust implementation.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Ensure that the error handling for incorrect minting mode when ACL whitelist is provided is robust. # Test: Search for error handling in minting mode validation. Expect: Robust error handling. rg --type rust $'InvalidMintingMode'Length of output: 343
74-89
: Validate tests for public mode with empty locked whitelist.Verification successful
The output from the executed script confirms that the test function
should_allow_installation_of_contract_with_empty_locked_whitelist_in_public_mode()
and its helper functionshould_allow_installation_of_contract_with_empty_locked_whitelist_in_public_mode_with_holder_mode()
are present in the codebase. These functions are designed to test the installation of a contract in public mode with an empty locked whitelist, covering differentNFTHolderMode
scenarios (Accounts, Contracts, Mixed).Given this information, it appears that the tests for public mode with an empty locked whitelist are implemented as expected, covering all necessary scenarios as outlined in the provided code snippet.
Final Response:
The tests for public mode with an empty locked whitelist are correctly implemented and cover all necessary scenarios as per the provided code snippet and the search results from the repository.
should_allow_installation_of_contract_with_empty_locked_whitelist_in_public_mode()
is the main test function.should_allow_installation_of_contract_with_empty_locked_whitelist_in_public_mode_with_holder_mode()
is used to test different holder modes.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the tests for public mode with an empty locked whitelist are correctly implemented and cover all necessary scenarios. # Test: Search for tests related to public mode with empty locked whitelist. Expect: Correct implementation and coverage. rg --type rust $'public_mode'Length of output: 682
112-144
: Review ACL whitelist and minting functionality test.Verification successful
The test in
modules/src/cep78/tests/acl.rs
appears to accurately reflect the intended behavior of the ACL whitelist and minting functionality. The test ensures that a user listed in the ACL whitelist can successfully mint a token and verifies the ownership of the minted token, which aligns with the expected behavior of such a feature.
- The test checks if the user is whitelisted.
- It sets the user as the caller and performs the minting.
- It verifies that the minted token is owned by the correct user.
This test setup and execution seem to correctly validate the ACL whitelist and minting functionality as intended.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Review the test covering ACL whitelist and minting functionality to ensure it accurately reflects the intended behavior. # Test: Search for tests covering ACL whitelist and minting functionality. Expect: Accurate reflection of intended behavior. rg --type rust $'acl_white_list'Length of output: 2234
146-177
: Examine error handling for unlisted accounts in minting.Verification successful
The review comment requested verification of the error handling for scenarios where unlisted accounts attempt to mint, focusing on the robustness and correctness of the implementation. The provided script searched for occurrences of
InvalidMinter
in the Rust files, which is the error expected to be thrown when an unlisted account attempts to mint.Analysis of Script Output:
- The error
InvalidMinter
is defined inmodules/src/cep78/error.rs
.- It is used in
modules/src/cep78/token.rs
in two places, indicating that the error is actively thrown in scenarios likely related to minting by unlisted accounts.- The test file
modules/src/cep78/tests/acl.rs
contains two instances whereInvalidMinter
is expected as an error output, which aligns with the test scenario described in the review comment.- Another test in
modules/src/cep78/tests/mint.rs
also expects this error, suggesting that the error handling is consistently tested across different scenarios.Conclusion:
The error handling for unlisted accounts attempting to mint appears to be robust and correctly implemented. The error
InvalidMinter
is not only defined but also actively used in relevant parts of the codebase, and its handling is covered in multiple test cases. This indicates a thorough approach to ensuring that unlisted accounts cannot mint, and if they attempt to, the system correctly identifies and handles the error.Given this information, the error handling for unlisted accounts in minting has been verified as robust and correctly implemented.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Examine the error handling for scenarios where unlisted accounts attempt to mint, ensuring it is robust and correctly implemented. # Test: Search for error handling related to unlisted accounts in minting. Expect: Robust and correct implementation. rg --type rust $'InvalidMinter'Length of output: 570
modules/src/cep78/modalities.rs (3)
63-79
: Check implementation and usage ofMintingMode
.Verification successful
The implementation and usage of
MintingMode
across the project appear to be consistent and correctly integrated. It is used in various modules for settings configurations, testing scenarios, and conditional logic in token management. The handling of related errors also suggests robust error management practices are in place.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check the implementation and usage of `MintingMode` to ensure it aligns with the system's requirements and is used consistently across the project. # Test: Search for usage of `MintingMode`. Expect: Consistent and correct implementation. rg --type rust $'MintingMode'Length of output: 5806
94-109
: Validate the addition ofNFTKind
enum.The addition of the
NFTKind
enum is well-implemented and serves to clarify the types of NFTs handled by the system. This is a positive change that enhances the modularity and clarity of the codebase.
180-196
: ExamineOwnershipMode
for potential issues.Verification successful
The output from the
rg
command shows extensive usage of theOwnershipMode
enum across various files in thecep78
module. This enum is used in settings, token handling, tests, and other utility functions, indicating its integral role in the system's functionality related to NFT ownership management.Key Observations:
- Enum Variants Usage: The enum variants (
Minter
,Assigned
,Transferable
) are actively used in conditional checks and function parameters across the module. This suggests that the enum is well-integrated into the logic of the system.- Error Handling: There are specific error cases (
InvalidOwnershipMode
,MissingOwnershipMode
) handled in the system, which shows that there are safeguards against incorrect usage or setup of ownership modes.- Test Coverage: The enum is used in various test scenarios, particularly with the
Transferable
mode being tested extensively. This indicates an emphasis on ensuring that transferable ownership functions as expected.Conclusion:
The
OwnershipMode
enum appears to be correctly implemented and extensively used throughout thecep78
module with appropriate error handling and test coverage. There are no immediate signs of misalignment with system requirements or potential issues based on the current usage patterns observed in the output.Given the thorough integration and testing of the
OwnershipMode
enum, as well as the handling of potential errors, it seems that the enum is functioning as intended within the system's architecture.
Based on the analysis, the review comment has been addressed adequately:
- The enum is well-utilized and integrated into the system.
- There are mechanisms in place to handle errors related to ownership modes.
- Extensive testing is performed, especially on the
Transferable
mode.Therefore, I conclude that there are no issues with the
OwnershipMode
enum as per the current implementation and usage within the codebase.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Examine the `OwnershipMode` enum for any potential issues or misalignments with the system's requirements. # Test: Search for usage and implications of `OwnershipMode`. Expect: No issues or misalignments. rg --type rust $'OwnershipMode'Length of output: 10507
modules/src/cep78/tests/metadata.rs (16)
29-56
: Ensure proper handling of immutable metadata updates.This test correctly checks that an attempt to update metadata in immutable mode results in a
ForbiddenMetadataUpdate
error, aligning with expected behavior.
58-67
: Validate deployment in mutable mode.The test verifies that deploying a contract with mutable metadata is successful, which is crucial for dynamic metadata management.
69-97
: Check handling of malformed metadata.This test ensures that the contract correctly rejects malformed metadata updates with a
FailedToParse721Metadata
error, which is essential for data integrity.
99-130
: Verify metadata update restrictions based on ownership.The test confirms that only the token owner can update the metadata, which is a critical security feature to prevent unauthorized changes.
133-230
: Enhance testing for valid metadata updates.This comprehensive test function covers various metadata kinds and identifier modes, ensuring that valid updates are processed correctly. It also checks for the emission of the
MetadataUpdated
event, which is important for tracking changes.
232-238
: Simplify test for NFT721 metadata updates.This test is a specific instance of the generic
should_allow_update_for_valid_metadata_based_on_kind
function, focusing on the NFT721 metadata kind. It's good to have specific tests for clarity and ease of understanding.
240-246
: Simplify test for CEP78 metadata updates.Similar to the previous comment, this test focuses on the CEP78 metadata kind, ensuring that the contract behaves as expected for this specific type of metadata.
248-254
: Simplify test for custom validated metadata updates.This test ensures that custom validated metadata can be updated correctly, which is crucial for contracts that need to enforce specific validation rules on their metadata.
256-281
: Ensure retrieval of metadata using token ID.This test checks that metadata can be correctly retrieved using a token ID, which is fundamental for any NFT-related operations.
283-312
: Ensure retrieval of metadata using token hash.This test verifies that metadata can be retrieved using a token hash, which is important for operations that use hash-based identifiers.
314-346
: Prevent duplicate minting using token hash.The test ensures that the contract prevents duplicate minting using the same token hash, which is crucial to maintain the uniqueness of tokens.
348-377
: Ensure retrieval of metadata using custom token hash.This test checks that metadata can be retrieved using a custom token hash, which is important for flexibility in handling different types of token identifiers.
379-415
: Prevent duplicate minting using custom token hash identifier.This test ensures that minting with a custom token hash identifier cannot be done more than once, which is essential for maintaining token uniqueness and integrity.
418-429
: Clarify requirement for valid JSON schema in custom validated kind.This test is commented out, suggesting it's either in development or deprecated. If active, it should validate the necessity of a JSON schema for custom validated metadata kinds.
431-448
: Validate JSON schema requirement for custom validated metadata.This test correctly checks that deploying a contract without a required JSON schema for custom validated metadata results in an error, which is crucial for ensuring that metadata meets specified standards.
450-479
: Confirm non-requirement of JSON schema for non-custom validated kinds.This function tests that a JSON schema is not required for metadata kinds other than custom validated, which is important for flexibility in metadata handling.
odra-vm/src/vm/odra_vm.rs (3)
179-182
: LGTM! The methodset_dict_value
correctly handles the byte slice keys and CLValue conversion.
187-193
: LGTM! The methodremove_dictionary
correctly handles the removal of dictionaries from the global state.
199-204
: LGTM! The methodget_dict_value
correctly handles the byte slice keys and error management.odra-casper/rpc-client/src/casper_client.rs (1)
129-132
: LGTM! The methodget_dictionary_value
correctly handles the byte slice keys and error management.modules/src/cep78/token.rs (1)
297-328
: Verify the logic for checking token ownership in theburn
function.The
burn
function includes logic to check if the caller is the owner or an approved operator of the token. Ensure that this logic correctly handles all cases, especially when the token owner is a contract or another non-standard account type. Consider adding tests to cover these scenarios.modules/src/cep78/tests/transfer.rs (19)
22-57
: Ensure consistent error handling for transfer operations.
59-115
: Validate event emission correctness in transfer scenarios.
177-223
: Ensure correct handling of revocation events.This function correctly handles the revocation of token transfer approvals and checks for the appropriate event emission.
238-261
: Validate error handling for approval restrictions.This function correctly handles scenarios where approving transfers is disallowed due to ownership mode restrictions.
263-305
: Check for consistency in approval and transfer logic.This function correctly implements the logic for token transfers under various conditions, including using an approved account.
321-377
: Ensure robust testing for repeated transfer attempts by the same account.This function robustly tests the scenario where a previously approved account attempts to transfer a token twice, correctly handling the expected error.
379-437
: Validate error handling for transfer attempts using revoked approval.This function correctly handles scenarios where a token transfer is attempted using a revoked approval hash, ensuring robust error handling.
457-493
: Ensure correct whitelisting and transfer logic between contracts and accounts.This function correctly implements the logic for transferring tokens between contracts and accounts, including checks for whitelisting.
495-527
: Validate error handling for unauthorized transfer attempts.This function correctly handles scenarios where a transfer attempt is made by a caller who is not the owner of the token.
530-554
: Ensure correct handling of token transfers in hash identifier mode.This function correctly implements the logic for transferring tokens in hash identifier mode, using the hash as the identifier.
557-592
: Validate error handling for unauthorized transfer attempts by non-approved contracts.This function correctly handles scenarios where a non-approved contract attempts to transfer a token, ensuring robust error handling.
655-698
: Validate the logic for transfer-only reporting in token transfers.This function correctly implements the logic for transferring tokens with transfer-only reporting, ensuring that the balances are correctly updated.
701-719
: Ensure robust error handling for self-approval attempts by owners.This function correctly handles scenarios where an owner attempts to approve itself for a transfer, ensuring robust error handling.
722-744
: Validate error handling for self-approval attempts by operators.This function correctly handles scenarios where an operator attempts to approve itself for a transfer, ensuring robust error handling.
748-766
: Ensure robust error handling for global self-approval attempts by owners.This function correctly handles scenarios where an owner attempts to set a global approval for itself, ensuring robust error handling.
769-840
: Validate the handling of transfer filter contract modes in token transfers.This function correctly implements the logic for handling different settings of a transfer filter contract in token transfers, ensuring that transfers are correctly allowed or denied based on the contract's return value.
843-867
: Validate error handling for unauthorized transfer attempts from contracts in package operator mode.This function correctly handles scenarios where a transfer from a contract is attempted without an operator in package operator mode, ensuring robust error handling.
876-904
: Ensure correct handling of transfers from contracts with an operator in package operator mode.This function correctly implements the logic for allowing transfers from contracts when an operator is set in package operator mode, ensuring that the transfers are correctly handled.
911-946
: Validate the logic for package operator approvals in package operator mode.This function correctly implements the logic for allowing package operators to approve transfers in package operator mode, ensuring that the approvals are correctly handled.
modules/src/cep78/token.rs
Outdated
acl_white_list: Maybe<Vec<Address>>, | ||
json_schema: Maybe<String>, | ||
burn_mode: Maybe<BurnMode>, | ||
operator_burn_mode: Maybe<bool>, | ||
owner_reverse_lookup_mode: Maybe<OwnerReverseLookupMode>, | ||
events_mode: Maybe<EventsMode>, | ||
transfer_filter_contract_contract: Maybe<Address>, | ||
additional_required_metadata: Maybe<Vec<NFTMetadataKind>>, | ||
optional_metadata: Maybe<Vec<NFTMetadataKind>> | ||
) { | ||
let installer = self.caller(); | ||
let minting_mode = minting_mode.unwrap_or_default(); | ||
let owner_reverse_lookup_mode = owner_reverse_lookup_mode.unwrap_or_default(); | ||
let acl_white_list = acl_white_list.unwrap_or_default(); | ||
let whitelist_mode = whitelist_mode.unwrap_or_default(); | ||
let json_schema = json_schema.unwrap_or_default(); | ||
let is_whitelist_empty = acl_white_list.is_empty(); | ||
|
||
// Revert if minting mode is not ACL and acl list is not empty | ||
if MintingMode::Acl != minting_mode && !is_whitelist_empty { | ||
self.revert(CEP78Error::InvalidMintingMode) | ||
} | ||
|
||
// Revert if minting mode is ACL or holder_mode is contracts and acl list is locked and empty | ||
if MintingMode::Acl == minting_mode | ||
&& is_whitelist_empty | ||
&& WhitelistMode::Locked == whitelist_mode | ||
{ | ||
self.revert(CEP78Error::EmptyACLWhitelist) | ||
} | ||
|
||
// NOTE: It is commented out to allow having mutable metadata with hash identifier. | ||
// NOTE: It's left for future reference. | ||
// if identifier_mode == NFTIdentifierMode::Hash | ||
// && metadata_mutability == MetadataMutability::Mutable | ||
// { | ||
// self.revert(CEP78Error::InvalidMetadataMutability) | ||
// } | ||
|
||
if ownership_mode == OwnershipMode::Minter | ||
&& minting_mode == MintingMode::Installer | ||
&& owner_reverse_lookup_mode == OwnerReverseLookupMode::Complete | ||
{ | ||
self.revert(CEP78Error::InvalidReportingMode) | ||
} | ||
|
||
// Check if schema is missing before checking its validity | ||
if nft_metadata_kind == NFTMetadataKind::CustomValidated && json_schema.is_empty() { | ||
self.revert(CEP78Error::MissingJsonSchema) | ||
} | ||
|
||
// OwnerReverseLookup TransfersOnly mode should be Transferable | ||
if OwnerReverseLookupMode::TransfersOnly == owner_reverse_lookup_mode | ||
&& OwnershipMode::Transferable != ownership_mode | ||
{ | ||
self.revert(CEP78Error::OwnerReverseLookupModeNotTransferable) | ||
} | ||
|
||
if ownership_mode != OwnershipMode::Transferable | ||
&& transfer_filter_contract_contract.is_some() | ||
{ | ||
self.revert(CEP78Error::TransferFilterContractNeedsTransferableMode) | ||
} | ||
|
||
self.data.init( | ||
collection_name, | ||
collection_symbol, | ||
total_token_supply, | ||
installer | ||
); | ||
self.settings.init( | ||
allow_minting.unwrap_or(true), | ||
minting_mode, | ||
ownership_mode, | ||
nft_kind, | ||
holder_mode.unwrap_or_default(), | ||
burn_mode.unwrap_or_default(), | ||
events_mode.unwrap_or_default(), | ||
operator_burn_mode.unwrap_or_default() | ||
); | ||
|
||
self.reverse_lookup | ||
.init(owner_reverse_lookup_mode, receipt_name); | ||
|
||
self.whitelist.init(acl_white_list.clone(), whitelist_mode); | ||
|
||
self.metadata.init( | ||
nft_metadata_kind, | ||
additional_required_metadata, | ||
optional_metadata, | ||
metadata_mutability, | ||
identifier_mode, | ||
json_schema | ||
); | ||
|
||
if let Maybe::Some(transfer_filter_contract_contract) = transfer_filter_contract_contract { | ||
self.transfer_filter_contract | ||
.set(transfer_filter_contract_contract); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure consistent error handling in the init
function.
The function contains multiple conditions that lead to reversion using self.revert(...)
. However, there's an inconsistency in the handling of the is_minter_or_assigned
condition (line 631). The function should revert if the condition is true
, but it currently reverts if false
. This is likely a logic error.
- if self.is_minter_or_assigned() {
+ if !self.is_minter_or_assigned() {
self.revert(CEP78Error::InvalidOwnershipMode)
}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
pub fn init( | |
&mut self, | |
collection_name: String, | |
collection_symbol: String, | |
total_token_supply: u64, | |
ownership_mode: OwnershipMode, | |
nft_kind: NFTKind, | |
identifier_mode: NFTIdentifierMode, | |
nft_metadata_kind: NFTMetadataKind, | |
metadata_mutability: MetadataMutability, | |
receipt_name: String, | |
allow_minting: Maybe<bool>, | |
minting_mode: Maybe<MintingMode>, | |
holder_mode: Maybe<NFTHolderMode>, | |
whitelist_mode: Maybe<WhitelistMode>, | |
acl_white_list: Maybe<Vec<Address>>, | |
json_schema: Maybe<String>, | |
burn_mode: Maybe<BurnMode>, | |
operator_burn_mode: Maybe<bool>, | |
owner_reverse_lookup_mode: Maybe<OwnerReverseLookupMode>, | |
events_mode: Maybe<EventsMode>, | |
transfer_filter_contract_contract: Maybe<Address>, | |
additional_required_metadata: Maybe<Vec<NFTMetadataKind>>, | |
optional_metadata: Maybe<Vec<NFTMetadataKind>> | |
) { | |
let installer = self.caller(); | |
let minting_mode = minting_mode.unwrap_or_default(); | |
let owner_reverse_lookup_mode = owner_reverse_lookup_mode.unwrap_or_default(); | |
let acl_white_list = acl_white_list.unwrap_or_default(); | |
let whitelist_mode = whitelist_mode.unwrap_or_default(); | |
let json_schema = json_schema.unwrap_or_default(); | |
let is_whitelist_empty = acl_white_list.is_empty(); | |
// Revert if minting mode is not ACL and acl list is not empty | |
if MintingMode::Acl != minting_mode && !is_whitelist_empty { | |
self.revert(CEP78Error::InvalidMintingMode) | |
} | |
// Revert if minting mode is ACL or holder_mode is contracts and acl list is locked and empty | |
if MintingMode::Acl == minting_mode | |
&& is_whitelist_empty | |
&& WhitelistMode::Locked == whitelist_mode | |
{ | |
self.revert(CEP78Error::EmptyACLWhitelist) | |
} | |
// NOTE: It is commented out to allow having mutable metadata with hash identifier. | |
// NOTE: It's left for future reference. | |
// if identifier_mode == NFTIdentifierMode::Hash | |
// && metadata_mutability == MetadataMutability::Mutable | |
// { | |
// self.revert(CEP78Error::InvalidMetadataMutability) | |
// } | |
if ownership_mode == OwnershipMode::Minter | |
&& minting_mode == MintingMode::Installer | |
&& owner_reverse_lookup_mode == OwnerReverseLookupMode::Complete | |
{ | |
self.revert(CEP78Error::InvalidReportingMode) | |
} | |
// Check if schema is missing before checking its validity | |
if nft_metadata_kind == NFTMetadataKind::CustomValidated && json_schema.is_empty() { | |
self.revert(CEP78Error::MissingJsonSchema) | |
} | |
// OwnerReverseLookup TransfersOnly mode should be Transferable | |
if OwnerReverseLookupMode::TransfersOnly == owner_reverse_lookup_mode | |
&& OwnershipMode::Transferable != ownership_mode | |
{ | |
self.revert(CEP78Error::OwnerReverseLookupModeNotTransferable) | |
} | |
if ownership_mode != OwnershipMode::Transferable | |
&& transfer_filter_contract_contract.is_some() | |
{ | |
self.revert(CEP78Error::TransferFilterContractNeedsTransferableMode) | |
} | |
self.data.init( | |
collection_name, | |
collection_symbol, | |
total_token_supply, | |
installer | |
); | |
self.settings.init( | |
allow_minting.unwrap_or(true), | |
minting_mode, | |
ownership_mode, | |
nft_kind, | |
holder_mode.unwrap_or_default(), | |
burn_mode.unwrap_or_default(), | |
events_mode.unwrap_or_default(), | |
operator_burn_mode.unwrap_or_default() | |
); | |
self.reverse_lookup | |
.init(owner_reverse_lookup_mode, receipt_name); | |
self.whitelist.init(acl_white_list.clone(), whitelist_mode); | |
self.metadata.init( | |
nft_metadata_kind, | |
additional_required_metadata, | |
optional_metadata, | |
metadata_mutability, | |
identifier_mode, | |
json_schema | |
); | |
if let Maybe::Some(transfer_filter_contract_contract) = transfer_filter_contract_contract { | |
self.transfer_filter_contract | |
.set(transfer_filter_contract_contract); | |
} | |
} | |
pub fn init( | |
&mut self, | |
collection_name: String, | |
collection_symbol: String, | |
total_token_supply: u64, | |
ownership_mode: OwnershipMode, | |
nft_kind: NFTKind, | |
identifier_mode: NFTIdentifierMode, | |
nft_metadata_kind: NFTMetadataKind, | |
metadata_mutability: MetadataMutability, | |
receipt_name: String, | |
allow_minting: Maybe<bool>, | |
minting_mode: Maybe<MintingMode>, | |
holder_mode: Maybe<NFTHolderMode>, | |
whitelist_mode: Maybe<WhitelistMode>, | |
acl_white_list: Maybe<Vec<Address>>, | |
json_schema: Maybe<String>, | |
burn_mode: Maybe<BurnMode>, | |
operator_burn_mode: Maybe<bool>, | |
owner_reverse_lookup_mode: Maybe<OwnerReverseLookupMode>, | |
events_mode: Maybe<EventsMode>, | |
transfer_filter_contract_contract: Maybe<Address>, | |
additional_required_metadata: Maybe<Vec<NFTMetadataKind>>, | |
optional_metadata: Maybe<Vec<NFTMetadataKind>> | |
) { | |
let installer = self.caller(); | |
let minting_mode = minting_mode.unwrap_or_default(); | |
let owner_reverse_lookup_mode = owner_reverse_lookup_mode.unwrap_or_default(); | |
let acl_white_list = acl_white_list.unwrap_or_default(); | |
let whitelist_mode = whitelist_mode.unwrap_or_default(); | |
let json_schema = json_schema.unwrap_or_default(); | |
let is_whitelist_empty = acl_white_list.is_empty(); | |
// Revert if minting mode is not ACL and acl list is not empty | |
if MintingMode::Acl != minting_mode && !is_whitelist_empty { | |
self.revert(CEP78Error::InvalidMintingMode) | |
} | |
// Revert if minting mode is ACL or holder_mode is contracts and acl list is locked and empty | |
if MintingMode::Acl == minting_mode | |
&& is_whitelist_empty | |
&& WhitelistMode::Locked == whitelist_mode | |
{ | |
self.revert(CEP78Error::EmptyACLWhitelist) | |
} | |
// NOTE: It is commented out to allow having mutable metadata with hash identifier. | |
// NOTE: It's left for future reference. | |
// if identifier_mode == NFTIdentifierMode::Hash | |
// && metadata_mutability == MetadataMutability::Mutable | |
// { | |
// self.revert(CEP78Error::InvalidMetadataMutability) | |
// } | |
if ownership_mode == OwnershipMode::Minter | |
&& minting_mode == MintingMode::Installer | |
&& owner_reverse_lookup_mode == OwnerReverseLookupMode::Complete | |
{ | |
self.revert(CEP78Error::InvalidReportingMode) | |
} | |
// Check if schema is missing before checking its validity | |
if nft_metadata_kind == NFTMetadataKind::CustomValidated && json_schema.is_empty() { | |
self.revert(CEP78Error::MissingJsonSchema) | |
} | |
// OwnerReverseLookup TransfersOnly mode should be Transferable | |
if OwnerReverseLookupMode::TransfersOnly == owner_reverse_lookup_mode | |
&& OwnershipMode::Transferable != ownership_mode | |
{ | |
self.revert(CEP78Error::OwnerReverseLookupModeNotTransferable) | |
} | |
if ownership_mode != OwnershipMode::Transferable | |
&& transfer_filter_contract_contract.is_some() | |
{ | |
self.revert(CEP78Error::TransferFilterContractNeedsTransferableMode) | |
} | |
if !self.is_minter_or_assigned() { | |
self.revert(CEP78Error::InvalidOwnershipMode) | |
} | |
self.data.init( | |
collection_name, | |
collection_symbol, | |
total_token_supply, | |
installer | |
); | |
self.settings.init( | |
allow_minting.unwrap_or(true), | |
minting_mode, | |
ownership_mode, | |
nft_kind, | |
holder_mode.unwrap_or_default(), | |
burn_mode.unwrap_or_default(), | |
events_mode.unwrap_or_default(), | |
operator_burn_mode.unwrap_or_default() | |
); | |
self.reverse_lookup | |
.init(owner_reverse_lookup_mode, receipt_name); | |
self.whitelist.init(acl_white_list.clone(), whitelist_mode); | |
self.metadata.init( | |
nft_metadata_kind, | |
additional_required_metadata, | |
optional_metadata, | |
metadata_mutability, | |
identifier_mode, | |
json_schema | |
); | |
if let Maybe::Some(transfer_filter_contract_contract) = transfer_filter_contract_contract { | |
self.transfer_filter_contract | |
.set(transfer_filter_contract_contract); | |
} | |
} |
#[test] | ||
fn should_disallow_minting_when_allow_minting_is_set_to_false() { | ||
let env = odra_test::env(); | ||
let args = default_args_builder() | ||
.nft_metadata_kind(NFTMetadataKind::NFT721) | ||
.allow_minting(false) | ||
.build(); | ||
let mut contract = Cep78HostRef::deploy(&env, args); | ||
|
||
assert_eq!( | ||
contract.try_mint( | ||
env.get_account(0), | ||
TEST_PRETTY_721_META_DATA.to_string(), | ||
Maybe::None | ||
), | ||
Err(CEP78Error::MintingIsPaused.into()), | ||
"should now allow minting when minting is disabled", | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure error message matches the function's intent.
- "should now allow minting when minting is disabled"
+ "should not allow minting when minting is disabled"
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
#[test] | |
fn should_disallow_minting_when_allow_minting_is_set_to_false() { | |
let env = odra_test::env(); | |
let args = default_args_builder() | |
.nft_metadata_kind(NFTMetadataKind::NFT721) | |
.allow_minting(false) | |
.build(); | |
let mut contract = Cep78HostRef::deploy(&env, args); | |
assert_eq!( | |
contract.try_mint( | |
env.get_account(0), | |
TEST_PRETTY_721_META_DATA.to_string(), | |
Maybe::None | |
), | |
Err(CEP78Error::MintingIsPaused.into()), | |
"should now allow minting when minting is disabled", | |
); | |
} | |
#[test] | |
fn should_disallow_minting_when_allow_minting_is_set_to_false() { | |
let env = odra_test::env(); | |
let args = default_args_builder() | |
.nft_metadata_kind(NFTMetadataKind::NFT721) | |
.allow_minting(false) | |
.build(); | |
let mut contract = Cep78HostRef::deploy(&env, args); | |
assert_eq!( | |
contract.try_mint( | |
env.get_account(0), | |
TEST_PRETTY_721_META_DATA.to_string(), | |
Maybe::None | |
), | |
Err(CEP78Error::MintingIsPaused.into()), | |
"should not allow minting when minting is disabled", | |
); | |
} |
#[ignore = "Reverse lookup is not implemented yet"] | ||
fn mint_should_return_dictionary_key_to_callers_owned_tokens() { | ||
let env = odra_test::env(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
The search results indicate that while the reverse lookup feature is referenced and partially discussed in the codebase, there is no definitive evidence that it is fully implemented and operational. The comments in the code suggest that certain aspects of the feature, like data writing for owner lookup and page table allocation, are planned or partially implemented. However, the absence of a clear indication of a complete and functional implementation supports the decision to keep the related test ignored for now.
modules/src/cep78/token.rs
: Mentions necessary steps to enable reverse lookup but requires explicit invocation, suggesting it's not fully integrated.modules/src/cep78/modalities.rs
: Discusses data handling for reverse lookup but also mentions an option where reverse lookup is not maintained, indicating conditional implementation.
Analysis chain
Clarify the status of the reverse lookup feature.
Please confirm whether the reverse lookup feature is implemented or if this test should remain ignored.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify if the reverse lookup feature is implemented.
# Test: Search for the implementation of reverse lookup. Expect: Implementation details or related comments.
rg --type rust 'reverse lookup'
Length of output: 575
let (mut contract, env) = default_token(); | ||
let owner = env.get_account(0); | ||
|
||
// TODO: should register the owner first to create a page for the owner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add necessary setup for the test to pass.
The comment indicates a missing setup step for registering the owner. Would you like me to help implement this setup step or open a GitHub issue to track this task?
// TODO: Reverse lookup not implemented yet | ||
/* | ||
let token_page = get_token_page_by_hash( | ||
&builder, | ||
&nft_contract_key, | ||
&Key::Account(*DEFAULT_ACCOUNT_ADDR), | ||
token_id_hash, | ||
); | ||
|
||
assert!(token_page[0])*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address the TODO regarding reverse lookup.
This TODO comment about reverse lookup not being implemented yet is linked to a large commented-out block of code. If you need assistance in implementing this feature or if it should be tracked via a GitHub issue, please let me know.
fn approve_token_for_transfer_should_add_entry_to_approved_dictionary( | ||
env: HostEnv, | ||
operator: Option<Address> | ||
) { | ||
let args = default_args_builder() | ||
.ownership_mode(OwnershipMode::Transferable) | ||
.owner_reverse_lookup_mode(OwnerReverseLookupMode::Complete) | ||
.events_mode(EventsMode::CES) | ||
.build(); | ||
let mut contract = Cep78HostRef::deploy(&env, args); | ||
|
||
let token_owner = env.get_account(0); | ||
contract.register_owner(Maybe::Some(token_owner)); | ||
contract.mint( | ||
token_owner, | ||
TEST_PRETTY_721_META_DATA.to_string(), | ||
Maybe::None | ||
); | ||
|
||
let spender = env.get_account(1); | ||
let token_id = 0u64; | ||
|
||
if let Some(operator) = operator { | ||
assert!(contract.try_set_approval_for_all(true, operator).is_ok()); | ||
} | ||
|
||
let approving_account = match operator { | ||
Some(operator) => operator, | ||
None => token_owner | ||
}; | ||
env.set_caller(approving_account); | ||
assert!(contract | ||
.try_approve(spender, Maybe::Some(token_id), Maybe::None) | ||
.is_ok()); | ||
|
||
let actual_approved_key = contract.get_approved(Maybe::Some(token_id), Maybe::None); | ||
assert_eq!(actual_approved_key, Some(spender)); | ||
|
||
// Expect Approval event. | ||
let expected_event = Approval::new( | ||
token_owner, | ||
spender, | ||
TokenIdentifier::Index(token_id).to_string() | ||
); | ||
assert!(env.emitted_event(contract.address(), &expected_event)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for potential simplifications in approval tests.
// Simplify the approval setting by directly using the `operator` option in the `env.set_caller` method.
env.set_caller(operator.unwrap_or(token_owner));
pub fn set_dictionary_value<T: CLTyped + ToBytes, U: AsRef<str>>( | ||
&self, | ||
dictionary_name: U, | ||
key: V, | ||
key: &[u8], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
The examination of the set_dictionary_value
function across different environments and modules in the codebase reveals varying approaches to error handling:
-
WASM and VM Environments: These environments use the function normally, passing the parameters to underlying systems without explicit error handling in the function itself. Errors are likely handled at a lower level or expected to be managed by the calling function.
-
Host Functions: Here, there is a check for the dictionary item key length, and an error is reverted if the key exceeds the maximum length. This shows explicit error handling within the function.
-
Livenet Environment: This environment explicitly panics if the function is called, indicating that such operations are not supported in this environment under normal circumstances.
-
Usage in Modules: In various modules, the function is used without additional error handling, suggesting reliance on the underlying implementations to manage errors.
Given these observations, the error handling for set_dictionary_value
is not entirely consistent across the project. Different environments handle errors in distinct ways, ranging from no explicit handling to specific checks and panic conditions. This inconsistency might be intentional due to the differing nature of operations in each environment, but it could benefit from a review to ensure that error handling strategies are clear and appropriate for each context.
Recommendation: Review the error handling strategies used in different environments for set_dictionary_value
to ensure they are appropriate and consider implementing more uniform error handling practices if feasible.
- WASM and VM Environments: Confirm if error handling at lower levels is sufficient.
- Host Functions: Maintain or adjust the explicit error checks as necessary.
- Livenet Environment: Ensure that the panic conditions are well-documented and understood by users of the environment.
- Module Usages: Consider adding error handling or documentation to clarify how errors should be managed.
Analysis chain
Ensure consistent error handling for set_dictionary_value
.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent error handling for `set_dictionary_value` across the project.
# Test: Search for the function usage. Expect: Consistent error handling.
rg --type rust $'set_dictionary_value'
Length of output: 1715
Script:
#!/bin/bash
# Description: Examine the implementations and usages of `set_dictionary_value` to verify error handling.
# Search for the function implementations and their surrounding code to check error handling mechanisms.
rg --type rust -C 10 "fn set_dictionary_value"
# Search for usages of `set_dictionary_value` and check how errors are handled or propagated.
rg --type rust -C 10 "set_dictionary_value\("
Length of output: 27173
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DEEP RABBIT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kubaplas, it seems like my previous message might have come as a surprise! If there's any part of the analysis you'd like to discuss further or if you have specific questions about the error handling strategies in different environments, feel free to let me know. I'm here to help!
/// Removes the dictionary from the contract storage. | ||
pub fn remove_dictionary<U: AsRef<str>>(&self, dictionary_name: U) { | ||
let dictionary_name = dictionary_name.as_ref(); | ||
self.backend.borrow().remove_dictionary(dictionary_name); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
The investigation into the remove_dictionary
function across various modules reveals that while the function's conceptual role remains consistent (i.e., removing a dictionary from some form of storage), the implementation details vary. These variations are primarily in the parameters accepted (string references vs. byte arrays) and the internal handling within the function. Here are the key observations:
- VM and Contract Environments: In
odra-vm
andodra-casper
modules, the function primarily accepts string references. However, in the VM state management (odra-vm/src/vm/odra_vm_state.rs
), a byte array is used, likely due to lower-level data handling requirements. - Host Functions and WASM Environment: The WASM environment uses host functions to bridge between WASM and the host environment, which consistently use string references.
- Core and Module-Specific Implementations: The core implementation in
core/src/contract_env.rs
is flexible, allowing any type that can be referenced as a string, which is a higher-level abstraction compared to other implementations.
These differences seem justified based on the specific needs and contexts of each module. Therefore, while the implementations are not identical, they are consistent in purpose and adapted to their respective environments.
Analysis chain
Verify that remove_dictionary
is implemented consistently across different modules.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent implementation of `remove_dictionary` across different modules.
# Test: Search for the function usage. Expect: Consistent implementation.
rg --type rust $'remove_dictionary'
Length of output: 1254
Benchmark report
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Out of diff range and nitpick comments (1)
examples/bin/cep78_on_livenet.rs (1)
28-34
: Consider removing or clarifying the purpose of commented-out code.The commented-out code for deploying a new contract and printing the token address (lines 28-30) could confuse maintainers or be accidentally uncommented. If this code is necessary for testing or future use, please add a comment explaining its purpose; otherwise, consider removing it.
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (4)
- examples/Cargo.toml (1 hunks)
- examples/bin/cep78_on_livenet.rs (1 hunks)
- modules/src/cep78/token.rs (1 hunks)
- modules/src/cep78/utils.rs (1 hunks)
Files skipped from review due to trivial changes (1)
- examples/Cargo.toml
Additional comments not posted (4)
examples/bin/cep78_on_livenet.rs (1)
76-78
: Verify the necessity of the high gas setting for contract deployment.The
deploy_contract
function sets a very high gas limit (line 76). While this might be necessary for contract deployment, it's important to ensure that this value is justified and optimized based on actual gas usage to avoid excessive costs.modules/src/cep78/utils.rs (1)
159-332
: Implementation ofInitArgsBuilder
follows best practices.The
InitArgsBuilder
struct correctly implements the builder pattern, providing a flexible and clear way to construct initialization arguments for a CEP-78 contract. The use of theMaybe
type for optional settings is a good practice.modules/src/cep78/token.rs (2)
297-328
: Implementation of theburn
function is robust and well-structured.The
burn
function in theCep78
module correctly implements the logic for burning tokens, including comprehensive checks for ownership and burn status. The use of helper methods enhances readability and maintainability.
398-446
: Implementation ofapprove
andrevoke
functions meets standards.The
approve
andrevoke
functions in theCep78
module are correctly implemented with necessary checks for ownership and token burn status. The use of events to log approvals and revocations is a good practice.
examples/bin/cep78_on_livenet.rs
Outdated
/// Loads a Cep78 contract. | ||
fn _load_contract(env: &HostEnv) -> Cep78HostRef { | ||
// casper-contract | ||
// let address = "hash-d4b8fa492d55ac7a515c0c6043d72ba43c49cd120e7ba7eec8c0a330dedab3fb"; | ||
// odra-contract | ||
let address = "hash-3d35238431c5c6fa1d7df70d73bfc2efd5a03fd5af99ab8c7828a56b2f330274"; | ||
let address = Address::from_str(address).unwrap(); | ||
Cep78HostRef::load(env, address) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using hardcoded addresses in production code.
The function _load_contract
uses a hardcoded address (line 53), which is not ideal for production environments as it reduces flexibility and maintainability. Consider passing the address as a parameter or retrieving it from a configuration file or environment variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- modules/src/cep78/utils.rs (1 hunks)
Additional comments not posted (1)
modules/src/cep78/utils.rs (1)
306-331
: The implementation ofInitArgsBuilder
follows the builder pattern correctly and is well-structured.
token_metadata: String, | ||
is_reverse_lookup_enabled: bool | ||
) -> (String, Address, String) { | ||
let nft_contract_address = self.nft_contract.get().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace unwrap
with safer error handling in MockContract
.
- let nft_contract_address = self.nft_contract.get().unwrap();
+ let nft_contract_address = self.nft_contract.get().ok_or("NFT contract address not found")?;
This change should be applied to all instances where unwrap
is used in this struct to prevent potential panics.
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
let nft_contract_address = self.nft_contract.get().unwrap(); | |
let nft_contract_address = self.nft_contract.get().ok_or("NFT contract address not found")?; |
Benchmark report
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- examples/bin/cep78_on_livenet.rs (1 hunks)
Additional comments not posted (2)
examples/bin/cep78_on_livenet.rs (2)
14-24
: Avoid using hardcoded addresses in production code.The function
load_contract
uses a hardcoded address (line 53), which is not ideal for production environments as it reduces flexibility and maintainability. Consider passing the address as a parameter or retrieving it from a configuration file or environment variable.
59-79
: LGTM! The deployment function is well-structured and uses appropriate defaults for the contract.
fn main() { | ||
let env = odra_casper_livenet_env::env(); | ||
|
||
// Deploy new contract. | ||
let mut token = deploy_contract(&env); | ||
println!("Token address: {}", token.address().to_string()); | ||
|
||
// Uncomment to load existing contract. | ||
// let mut token = load_contract(&env, CASPER_CONTRACT_ADDRESS); | ||
// println!("Token name: {}", token.get_collection_name()); | ||
|
||
env.set_gas(3_000_000_000u64); | ||
let owner = env.caller(); | ||
let recipient = | ||
Address::from_str(RECIPIENT_ADDRESS).expect("Should be a valid recipient address"); | ||
// casper contract may return a result or not, so deserialization may fail and it's better to use `try_transfer`/`try_mint`/`try_burn` methods | ||
let _ = token.try_mint(owner, CEP78_METADATA.to_string(), Maybe::None); | ||
println!("Owner's balance: {:?}", token.balance_of(owner)); | ||
println!("Recipient's balance: {:?}", token.balance_of(recipient)); | ||
let token_id = token.get_number_of_minted_tokens() - 1; | ||
let _ = token.try_transfer(Maybe::Some(token_id), Maybe::None, owner, recipient); | ||
|
||
println!("Owner's balance: {:?}", token.balance_of(owner)); | ||
println!("Recipient's balance: {:?}", token.balance_of(recipient)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error handling and avoid hardcoded values.
Consider enhancing the error handling around try_mint
and try_transfer
methods to ensure that failures are handled gracefully. Additionally, avoid using hardcoded values such as gas amounts and instead retrieve them from a configuration or environment variable to increase flexibility.
Benchmark report
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- modules/src/cep78/events.rs (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- modules/src/cep78/events.rs
Benchmark report
|
Summary by CodeRabbit
New Features
Enhancements
Cargo.toml
to include new dependencies enhancing functionality.Bug Fixes
.gitignore
to exclude system-specific files like.DS_Store
.Refactor
Chores
install-cargo-odra
command in thejustfile
to specify the stable toolchain for installation.