-
Notifications
You must be signed in to change notification settings - Fork 4
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
Nft Staking #11
base: main
Are you sure you want to change the base?
Nft Staking #11
Conversation
WalkthroughThe updates introduce a robust NFT staking module for smart contracts, enabling functionalities like staking, unstaking, and claiming rewards. This new module enhances state management and error handling while providing a user-friendly experience for NFT holders. Additionally, integration tests ensure comprehensive validation of all features, promoting reliability and security in the contract's operations. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Contract
participant State
User ->> Contract: Receive NFT
Contract ->> State: Update Staker Details
State ->> Contract: Confirm Receipt
User ->> Contract: Claim Reward
Contract ->> State: Calculate Rewards
State ->> Contract: Return Rewards
Contract ->> User: Transfer Rewards
User ->> Contract: Unstake NFT
Contract ->> State: Update Unbonding Status
State ->> Contract: Confirm Unstake
User ->> Contract: Claim Unstaked NFT
Contract ->> State: Check Unbonding Period
State ->> Contract: Confirm Claim
Contract ->> User: Transfer NFT
Poem
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 Configuration File (
|
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: 10
Outside diff range, codebase verification and nitpick comments (3)
ADOs/nft-staking/src/helpers.rs (1)
1-27
: Helper Functions Approved with Suggestion for ImprovementThe helper functions in
helpers.rs
are well-designed and facilitate contract interaction effectively. However, adding documentation comments for the public functions would improve maintainability and clarity for other developers.+/// Returns the address of the contract. pub fn addr(&self) -> Addr {
ADOs/nft-staking/src/state.rs (1)
68-77
: Check error handling inget_asset_detail
.The
calculate_pending_rewards
function does not handle errors gracefully. It usesunwrap_or_default
andunwrap
, which can cause the program to panic if any operation fails. This needs to be addressed to ensure robust error handling.
- Modify the
calculate_pending_rewards
function to handle errors properly instead of usingunwrap_or_default
andunwrap
.Analysis chain
Check error handling in
get_asset_detail
.This function modifies the
pending_rewards
field based on a calculation, which is a critical operation. Ensure thatcalculate_pending_rewards
handles errors internally since its result directly affects the state.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify error handling in the calculate_pending_rewards function. rg --type rust -A 5 "fn calculate_pending_rewards"Length of output: 434
Script:
#!/bin/bash # Description: Retrieve the full implementation of the calculate_pending_rewards function to check for error handling. rg --type rust -A 50 "fn calculate_pending_rewards" ADOs/nft-staking/src/state.rsLength of output: 976
ADOs/nft-staking/src/contract.rs (1)
67-107
: Execution function handles different messages appropriately.The
execute
function routes different message types to their respective handlers effectively. The pattern matching in Rust is used correctly to handle different types ofExecuteMsg
.Consider removing commented code if it's not intended for future use to keep the codebase clean and maintainable.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (1)
ADOs/nft-staking/Cargo.lock
is excluded by!**/*.lock
Files selected for processing (21)
- ADOs/nft-staking/.cargo/config (1 hunks)
- ADOs/nft-staking/.circleci/config.yml (1 hunks)
- ADOs/nft-staking/.editorconfig (1 hunks)
- ADOs/nft-staking/.github/workflows/Basic.yml (1 hunks)
- ADOs/nft-staking/.github/workflows/Release.yml (1 hunks)
- ADOs/nft-staking/.gitignore (1 hunks)
- ADOs/nft-staking/Cargo.toml (1 hunks)
- ADOs/nft-staking/LICENSE (1 hunks)
- ADOs/nft-staking/NOTICE (1 hunks)
- ADOs/nft-staking/README.md (1 hunks)
- ADOs/nft-staking/src/bin/schema.rs (1 hunks)
- ADOs/nft-staking/src/config.rs (1 hunks)
- ADOs/nft-staking/src/contract.rs (1 hunks)
- ADOs/nft-staking/src/error.rs (1 hunks)
- ADOs/nft-staking/src/execute.rs (1 hunks)
- ADOs/nft-staking/src/helpers.rs (1 hunks)
- ADOs/nft-staking/src/integration_tests.rs (1 hunks)
- ADOs/nft-staking/src/lib.rs (1 hunks)
- ADOs/nft-staking/src/msg.rs (1 hunks)
- ADOs/nft-staking/src/query.rs (1 hunks)
- ADOs/nft-staking/src/state.rs (1 hunks)
Files skipped from review due to trivial changes (5)
- ADOs/nft-staking/.cargo/config
- ADOs/nft-staking/.gitignore
- ADOs/nft-staking/LICENSE
- ADOs/nft-staking/NOTICE
- ADOs/nft-staking/src/config.rs
Additional context used
LanguageTool
ADOs/nft-staking/README.md
[uncategorized] ~7-~7: Possible missing comma found.
Context: ...on To see what's involved in making an ADO check out our documentation [here](http...(AI_HYDRA_LEO_MISSING_COMMA)
[uncategorized] ~18-~18: You might be missing the article “a” here.
Context: ...et coding. ## Creating a new repo from template Assuming you have a recent version of ...(AI_EN_LECTOR_MISSING_DETERMINER_A)
[misspelling] ~52-~52: Use “an” instead of ‘a’ if the following word starts with a vowel sound, e.g. ‘an article’, ‘an hour’.
Context: ...eate a Repo After generating, you have a initialized local git repo, but no comm...(EN_A_VS_AN)
[uncategorized] ~53-~53: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...commits, and no remote. Go to a server (eg. github) and create a new upstream repo ...(E_G)
[style] ~73-~73: ‘exact same’ might be wordy. Consider a shorter alternative.
Context: ...s with--locked
to ensure it uses the exact same versions as you have locally. This also...(EN_WORDINESS_PREMIUM_EXACT_SAME)
Markdownlint
ADOs/nft-staking/README.md
35-35: null
Emphasis used instead of a heading(MD036, no-emphasis-as-heading)
Additional comments not posted (33)
ADOs/nft-staking/.editorconfig (1)
1-11
: Editor Configuration ApprovedThe
.editorconfig
file is well-configured to ensure consistent coding styles across the project, particularly with the Rust-specific indentation setting which aligns with common Rust conventions.ADOs/nft-staking/src/lib.rs (1)
1-12
: Module Organization ApprovedThe organization of modules in
lib.rs
is clear and modular, which will facilitate maintenance and scalability. The re-export ofContractError
is a good practice for centralized error management.ADOs/nft-staking/src/bin/schema.rs (1)
1-11
: Schema Generation Logic ApprovedThe schema generation setup in
schema.rs
is correctly implemented usingcosmwasm_schema::write_api
. This setup is crucial for contract interaction and is well configured.ADOs/nft-staking/.github/workflows/Release.yml (2)
3-5
: Confirm the trigger event for the workflow.The workflow is triggered on the creation of a release. Ensure this aligns with the project's release strategy.
Verification successful
The trigger event for the workflow is correctly configured.
The workflow is appropriately triggered by the creation of a release, and there are no other workflows in the repository that conflict with this trigger.
- No conflicting or redundant workflows found.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify if the release trigger aligns with other workflows in the repository. # Test: Search for other workflows that might be triggered on release to ensure there are no conflicts or redundancies. rg --type yaml 'on:\s+release' -g '*.yml'Length of output: 192
Script:
#!/bin/bash # Description: Verify if the release trigger aligns with other workflows in the repository. # Test: Search for other workflows that might be triggered on release to ensure there are no conflicts or redundancies. rg --type yaml 'on:\s+release' -g '*.yml' --debugLength of output: 6571
Script:
#!/bin/bash # Description: Verify if the release trigger aligns with other workflows in the repository. # Test: Search for other workflows that might be triggered on release to ensure there are no conflicts or redundancies. rg --type yaml 'on:\s+release' -g '*.yml' --hiddenLength of output: 52
11-35
: Review the workflow steps for correctness and security.The steps include checking out the repository, installing a cargo run script, optimizing the wasm binary, and uploading it to a release. The usage of
actions/checkout@v2
andactions-rs/cargo@v1
is standard and appropriate. However, ensure that theGITHUB_TOKEN
andsecrets.GITHUB_TOKEN
are properly managed and that the permissions are correctly configured.Verification successful
Workflow steps are correct and secure.
The usage of
GITHUB_TOKEN
andsecrets.GITHUB_TOKEN
in the workflow file is standard and appropriate. The actions used (actions/checkout@v2
,actions-rs/cargo@v1
,bruceadams/[email protected]
, andsvenstaro/upload-release-action@v2
) are well-known and reliable.
- Lines 27 and 31: Proper usage of
GITHUB_TOKEN
andsecrets.GITHUB_TOKEN
.- Actions used are standard and secure.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the GitHub token permissions in the repository settings. # Test: This script is conceptual as token permissions can only be verified manually through the GitHub UI. echo "Please manually verify the GITHUB_TOKEN permissions in the repository settings."Length of output: 168
Script:
#!/bin/bash # Description: Verify the usage of GITHUB_TOKEN and secrets.GITHUB_TOKEN in the workflow file for potential security issues. # Search for the usage of GITHUB_TOKEN in the workflow file echo "Checking for GITHUB_TOKEN usage in the workflow file..." grep -n 'GITHUB_TOKEN' ADOs/nft-staking/.github/workflows/Release.yml # Search for the usage of secrets.GITHUB_TOKEN in the workflow file echo "Checking for secrets.GITHUB_TOKEN usage in the workflow file..." grep -n 'secrets.GITHUB_TOKEN' ADOs/nft-staking/.github/workflows/Release.yml # List all actions used in the workflow file to check for any potential security issues echo "Listing all actions used in the workflow file..." grep -n 'uses:' ADOs/nft-staking/.github/workflows/Release.ymlLength of output: 938
ADOs/nft-staking/Cargo.toml (1)
1-50
: Review the package configuration and dependencies.The package configuration is correctly set with appropriate authors and versioning. Dependencies like
cosmwasm-std
andcw721
are correctly specified for a blockchain contract. The build settings are optimized for release, which is suitable for a production environment.ADOs/nft-staking/.circleci/config.yml (1)
3-61
: Review the CircleCI configuration for Docker operations.The configuration uses Docker layer caching and conditional logic for pushing images, which is efficient. However, ensure that the Docker credentials (
DOCKER_USER
andDOCKER_PASS
) are securely stored in CircleCI's environment variables and not hardcoded.ADOs/nft-staking/.github/workflows/Basic.yml (4)
1-1
: General Comment: Good reference usage.The comment indicates that this workflow is based on a well-known example, which is a good practice for maintainability and understanding.
3-3
: General Comment: Trigger events specified.The workflow is triggered on
push
andpull_request
events, which is typical and ensures that the code is tested and linted frequently.
7-39
: General Comment: Test job configuration.The test job is well structured with steps for checking out code, setting up the Rust environment, running unit tests, and compiling the WASM contract. Each step uses appropriate actions and specifies necessary configurations such as toolchain version and environment variables.
40-75
: General Comment: Lint and schema generation job.This job handles linting and schema generation. It is correctly set up with steps for checking out code, installing toolchain components, running
cargo fmt
andclippy
, and ensuring no schema changes are uncommitted. This ensures code quality and consistency.ADOs/nft-staking/src/query.rs (4)
12-18
: General Comment: Configuration query implementation.The function
query_config
correctly retrieves configuration settings from the contract's state. The use ofCONFIG.load
with proper error handling is commendable.
21-23
: General Comment: Rewards query implementation.The function
query_rewards_per_token
is implemented correctly, fetching rewards data efficiently and handling errors appropriately.
26-31
: General Comment: Stakers query implementation.The function
query_stakers
efficiently lists all stakers. The use of.keys
withOrder::Ascending
is appropriate for this context.
62-70
: General Comment: Asset detail query implementation.This function correctly fetches detailed information about a specific asset. The error handling and structure of the response are appropriate.
ADOs/nft-staking/src/msg.rs (4)
17-28
: General Comment: Instantiate message structure.The
InstantiateMsg
struct is well-defined with clear documentation and appropriate data types. The inclusion of optional fields for unbonding period and payout window allows flexibility in contract configuration.
30-49
: General Comment: Execution message enumeration.The
ExecuteMsg
enum covers all necessary operations for the NFT staking functionality, such as receiving NFTs, claiming rewards, and updating configuration. The structure is clear and well-documented.
51-68
: General Comment: Query message enumeration.The
QueryMsg
enum is comprehensive, covering all necessary queries for the contract. The use of custom response types for each query ensures type safety and clarity.
70-104
: General Comment: Validation logic inInstantiateMsg
.The validation logic is robust, ensuring no duplicated assets, non-zero rewards, and adherence to minimum requirements for unbonding periods and payout windows. This prevents common configuration errors and enforces contract integrity.
ADOs/nft-staking/README.md (2)
1-3
: General Comment: Introduction and reference to template.The introduction clearly states the purpose of the repository and references the original template, which is helpful for users to understand the context.
5-17
: General Comment: Documentation and template usage instructions.The documentation links and instructions on using the template are clear and concise, providing users with necessary resources to get started.
Tools
LanguageTool
[uncategorized] ~7-~7: Possible missing comma found.
Context: ...on To see what's involved in making an ADO check out our documentation [here](http...(AI_HYDRA_LEO_MISSING_COMMA)
ADOs/nft-staking/src/state.rs (4)
8-14
: Config struct definition looks good.The
Config
struct is well-defined and appropriately uses Rust'sDefault
trait to provide default values. The use of thecw_serde
attribute ensures compatibility with CosmWasm's serialization requirements.
16-21
: StakerDetail struct definition is appropriate.The
StakerDetail
struct is simple and efficiently stores a list of assets. It is correctly marked for serialization and uses theDefault
trait, which is suitable for initializing new staker entries.
23-32
: AssetDetail struct definition is comprehensive.The
AssetDetail
struct includes all necessary fields to track the staking details of an asset, including rewards and timestamps. The optionalunstaked_at
field is a good design choice, allowing for flexibility in handling the staking lifecycle.
63-66
: Proper error handling inget_staker_detail
.The function correctly handles potential errors by propagating them using
?
, which is a good practice in Rust for error handling.ADOs/nft-staking/src/integration_tests.rs (2)
1-8
: Use of appropriate testing framework and setup.The use of
#![cfg(test)]
ensures that this code is only compiled in test mode, which is good for separating test code from production code. The imports and setup usingcosmwasm_std
andcw_multi_test
are appropriate for the intended testing of a CosmWasm contract.
10-44
: Correct setup of contract wrappers and address generation.The functions
contract_nft_staking
andcontract_cw721
correctly wrap the contract logic for instantiation, execution, and querying. The use ofMockApiBech32
for address generation ingenerate_mock_address
is a standard approach in testing environments.ADOs/nft-staking/src/contract.rs (2)
109-129
: Query handlers are implemented correctly.The
query
function correctly handles different query messages and encodes the responses properly. The use ofencode_binary
ensures that the responses are correctly formatted for the CosmWasm environment.
131-261
: Comprehensive unit tests for contract instantiation.The tests cover various scenarios including valid instantiation, error handling for invalid asset denominations, and checks for empty or duplicated rewards. These tests are crucial for ensuring the contract behaves as expected under different conditions.
ADOs/nft-staking/src/execute.rs (4)
70-104
: Claim rewards function correctly calculates and distributes rewards.The
claim_reward
function efficiently processes pending rewards and sends the correct amount to the staker. The separation of concerns and clear logic flow in this function are commendable.
106-149
: Unstake function correctly handles asset unstaking with proper checks.The
unstake
function includes necessary checks such as whether the asset is already unstaked and if the caller is authorized. This prevents unauthorized access and double unstaking, which are critical for contract security.
151-223
: Claim asset function ensures all conditions are met before asset transfer.The
claim_asset
function correctly checks that the asset has passed the unbonding period and that the caller is authorized before allowing the asset claim. This prevents premature claims and ensures that only rightful owners can claim assets.
225-260
: Config update function includes necessary validations and updates.The
update_config
function properly checks for authorization and validates the new unbonding period before updating the configuration. This prevents unauthorized configuration changes and ensures that updates meet the required conditions.
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: 4
Outside diff range, codebase verification and nitpick comments (5)
ADOs/nft-staking/src/execute.rs (5)
18-68
: Consider adding detailed logging inreceive_cw721
.Adding more detailed logging for each step can aid in debugging and monitoring contract interactions.
+ .add_attribute("action", "validate_nft") + .add_attribute("action", "update_staker_details") + .add_attribute("action", "update_asset_details")
70-104
: Consider adding detailed logging inclaim_reward
.Adding more detailed logging for each step can aid in debugging and monitoring contract interactions.
+ .add_attribute("action", "validate_staker") + .add_attribute("action", "process_rewards")
106-149
: Consider adding detailed logging inunstake
.Adding more detailed logging for each step can aid in debugging and monitoring contract interactions.
+ .add_attribute("action", "validate_staker") + .add_attribute("action", "update_asset_details")
151-223
: Consider adding detailed logging inclaim_asset
.Adding more detailed logging for each step can aid in debugging and monitoring contract interactions.
+ .add_attribute("action", "validate_unstaking_period") + .add_attribute("action", "update_staker_details") + .add_attribute("action", "transfer_nft")
225-801
: Consider adding detailed logging inupdate_config
.Adding more detailed logging for each step can aid in debugging and monitoring contract interactions.
+ .add_attribute("action", "validate_owner") + .add_attribute("action", "update_config")
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (3)
- ADOs/nft-staking/src/execute.rs (1 hunks)
- ADOs/nft-staking/src/msg.rs (1 hunks)
- ADOs/nft-staking/src/state.rs (1 hunks)
Additional comments not posted (12)
ADOs/nft-staking/src/msg.rs (6)
1-15
: LGTM! Imports are necessary and relevant.The imports are appropriate and necessary for the functionality provided in the file.
17-28
: LGTM!InstantiateMsg
struct is well-defined.The struct includes necessary fields with appropriate comments and allows for flexibility using
Option
.
30-49
: LGTM!ExecuteMsg
enum covers all necessary execution messages.The enum is comprehensive and includes all required messages for the contract functionality.
51-68
: LGTM!QueryMsg
enum covers all necessary query messages.The enum is comprehensive and includes all required messages for querying contract state.
70-104
: LGTM!InstantiateMsg
validation logic is thorough.The validation logic includes necessary checks for duplicate assets, zero rewards, empty rewards, and minimum periods.
107-130
: LGTM! Response structs are well-defined.The response structs include necessary fields for configuration, rewards, stakers, and asset details.
ADOs/nft-staking/src/state.rs (5)
1-7
: LGTM! Imports are necessary and relevant.The imports are appropriate and necessary for the functionality provided in the file.
8-32
: LGTM! State structs are well-defined.The structs include necessary fields with appropriate comments and use the
Default
trait for initializing default values.
34-40
: LGTM! State constants are well-defined.The constants use appropriate storage utilities from
cw_storage_plus
.
68-77
: Ensure proper error handling inget_asset_detail
.The function uses
.unwrap()
which could panic if there's an error during storage operations. It's safer to handle these potential errors gracefully to avoid panicking the contract.- let mut asset_detail = ASSET_DETAILS.load(store, (nft_address, token_id))?; + let mut asset_detail = ASSET_DETAILS.load(store, (nft_address, token_id)).map_err(|_| ContractError::StorageError)?;Likely invalid or redundant comment.
63-66
: Ensure proper error handling inget_staker_detail
.The function uses
.unwrap()
which could panic if there's an error during storage operations. It's safer to handle these potential errors gracefully to avoid panicking the contract.- let staker_detail = STAKER_DETAILS.load(store, &staker)?; + let staker_detail = STAKER_DETAILS.load(store, &staker).map_err(|_| ContractError::StorageError)?;Likely invalid or redundant comment.
ADOs/nft-staking/src/execute.rs (1)
1-16
: LGTM! Imports are necessary and relevant.The imports are appropriate and necessary for the functionality provided in the file.
ADOs/nft-staking/src/state.rs
Outdated
pub fn calculate_pending_rewards( | ||
store: &dyn Storage, | ||
block: &BlockInfo, | ||
asset_detail: AssetDetails, | ||
) -> Uint128 { | ||
// For nfts in unbonding period, just return original pending rewards | ||
if asset_detail.unstaked_at.is_some() { | ||
return asset_detail.pending_rewards; | ||
} | ||
|
||
let unpaid_duration: u128 = block | ||
.time | ||
.nanos() | ||
.checked_sub(asset_detail.updated_at.nanos()) | ||
.unwrap_or_default() as u128; | ||
let config = CONFIG.load(store).unwrap_or_default(); | ||
|
||
let window_count = Uint128::new(unpaid_duration.checked_div(config.payout_window.nanos() as u128).unwrap()); | ||
|
||
let reward_per_window = REWARDS_PER_TOKEN | ||
.load(store, &asset_detail.nft_address) | ||
.unwrap_or_default(); | ||
|
||
window_count | ||
.checked_mul(reward_per_window) | ||
.unwrap_or_default() | ||
.checked_add(asset_detail.pending_rewards) | ||
.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.
Ensure proper error handling in calculate_pending_rewards
.
The function uses .unwrap()
which could panic if there's an error during storage operations. It's safer to handle these potential errors gracefully to avoid panicking the contract.
- let config = CONFIG.load(store).unwrap_or_default();
+ let config = CONFIG.load(store).map_err(|_| ContractError::StorageError)?;
Committable suggestion was skipped due to low confidence.
ADOs/nft-staking/src/state.rs
Outdated
pub fn process_pending_rewards( | ||
store: &mut dyn Storage, | ||
block: &BlockInfo, | ||
nft_address: String, | ||
token_id: String, | ||
) -> Result<Uint128, ContractError> { | ||
let mut asset_detail = ASSET_DETAILS.load(store, (nft_address.clone(), token_id.clone()))?; | ||
let pending_rewards = calculate_pending_rewards(store, block, asset_detail.clone()); | ||
ensure!(!pending_rewards.is_zero(), ContractError::ZeroReward {}); | ||
|
||
let unpaid_duration = block | ||
.time | ||
.nanos() | ||
.checked_sub(asset_detail.updated_at.nanos()) | ||
.unwrap_or_default(); | ||
|
||
let config = CONFIG.load(store).unwrap_or_default(); | ||
let remainder = unpaid_duration % config.payout_window.nanos(); | ||
asset_detail.pending_rewards = Uint128::zero(); | ||
asset_detail.updated_at = Milliseconds::from_nanos(block.time.nanos().checked_sub(remainder).unwrap()); | ||
ASSET_DETAILS.save(store, (nft_address, token_id), &asset_detail)?; | ||
Ok(pending_rewards) | ||
} |
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 proper error handling in process_pending_rewards
.
The function uses .unwrap()
which could panic if there's an error during storage operations. It's safer to handle these potential errors gracefully to avoid panicking the contract.
- let config = CONFIG.load(store).unwrap_or_default();
+ let config = CONFIG.load(store).map_err(|_| ContractError::StorageError)?;
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
pub fn process_pending_rewards( | |
store: &mut dyn Storage, | |
block: &BlockInfo, | |
nft_address: String, | |
token_id: String, | |
) -> Result<Uint128, ContractError> { | |
let mut asset_detail = ASSET_DETAILS.load(store, (nft_address.clone(), token_id.clone()))?; | |
let pending_rewards = calculate_pending_rewards(store, block, asset_detail.clone()); | |
ensure!(!pending_rewards.is_zero(), ContractError::ZeroReward {}); | |
let unpaid_duration = block | |
.time | |
.nanos() | |
.checked_sub(asset_detail.updated_at.nanos()) | |
.unwrap_or_default(); | |
let config = CONFIG.load(store).unwrap_or_default(); | |
let remainder = unpaid_duration % config.payout_window.nanos(); | |
asset_detail.pending_rewards = Uint128::zero(); | |
asset_detail.updated_at = Milliseconds::from_nanos(block.time.nanos().checked_sub(remainder).unwrap()); | |
ASSET_DETAILS.save(store, (nft_address, token_id), &asset_detail)?; | |
Ok(pending_rewards) | |
} | |
pub fn process_pending_rewards( | |
store: &mut dyn Storage, | |
block: &BlockInfo, | |
nft_address: String, | |
token_id: String, | |
) -> Result<Uint128, ContractError> { | |
let mut asset_detail = ASSET_DETAILS.load(store, (nft_address.clone(), token_id.clone()))?; | |
let pending_rewards = calculate_pending_rewards(store, block, asset_detail.clone()); | |
ensure!(!pending_rewards.is_zero(), ContractError::ZeroReward {}); | |
let unpaid_duration = block | |
.time | |
.nanos() | |
.checked_sub(asset_detail.updated_at.nanos()) | |
.unwrap_or_default(); | |
let config = CONFIG.load(store).map_err(|_| ContractError::StorageError)?; | |
let remainder = unpaid_duration % config.payout_window.nanos(); | |
asset_detail.pending_rewards = Uint128::zero(); | |
asset_detail.updated_at = Milliseconds::from_nanos(block.time.nanos().checked_sub(remainder).unwrap()); | |
ASSET_DETAILS.save(store, (nft_address, token_id), &asset_detail)?; | |
Ok(pending_rewards) | |
} |
pub fn get_rewards_per_token(store: &dyn Storage) -> Result<Vec<(String, u128)>, ContractError> { | ||
Ok(REWARDS_PER_TOKEN | ||
.range_raw(store, None, None, cosmwasm_std::Order::Ascending) | ||
.map(|item| { | ||
let item = item.unwrap(); | ||
(String::from_utf8(item.0).unwrap(), item.1.u128()) | ||
}) | ||
.collect()) | ||
} |
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 proper error handling in get_rewards_per_token
.
The function uses .unwrap()
which could panic if there's an error during decoding. It's safer to handle these potential errors gracefully to avoid panicking the contract.
- let item = item.unwrap();
+ let item = item.map_err(|_| ContractError::StorageError)?;
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
pub fn get_rewards_per_token(store: &dyn Storage) -> Result<Vec<(String, u128)>, ContractError> { | |
Ok(REWARDS_PER_TOKEN | |
.range_raw(store, None, None, cosmwasm_std::Order::Ascending) | |
.map(|item| { | |
let item = item.unwrap(); | |
(String::from_utf8(item.0).unwrap(), item.1.u128()) | |
}) | |
.collect()) | |
} | |
pub fn get_rewards_per_token(store: &dyn Storage) -> Result<Vec<(String, u128)>, ContractError> { | |
Ok(REWARDS_PER_TOKEN | |
.range_raw(store, None, None, cosmwasm_std::Order::Ascending) | |
.map(|item| { | |
let item = item.map_err(|_| ContractError::StorageError)?; | |
(String::from_utf8(item.0).unwrap(), item.1.u128()) | |
}) | |
.collect()) | |
} |
pub fn set_rewards_per_token( | ||
store: &mut dyn Storage, | ||
rewards_per_token: Vec<(String, u128)>, | ||
) -> Result<(), ContractError> { | ||
rewards_per_token.iter().for_each(|item| { | ||
REWARDS_PER_TOKEN | ||
.save(store, &item.0, &Uint128::from(item.1)) | ||
.unwrap(); | ||
}); | ||
Ok(()) | ||
} |
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 proper error handling in set_rewards_per_token
.
The function uses .unwrap()
which could panic if there's an error during storage operations. It's safer to handle these potential errors gracefully to avoid panicking the contract.
- .unwrap();
+ .map_err(|_| ContractError::StorageError)?;
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
pub fn set_rewards_per_token( | |
store: &mut dyn Storage, | |
rewards_per_token: Vec<(String, u128)>, | |
) -> Result<(), ContractError> { | |
rewards_per_token.iter().for_each(|item| { | |
REWARDS_PER_TOKEN | |
.save(store, &item.0, &Uint128::from(item.1)) | |
.unwrap(); | |
}); | |
Ok(()) | |
} | |
pub fn set_rewards_per_token( | |
store: &mut dyn Storage, | |
rewards_per_token: Vec<(String, u128)>, | |
) -> Result<(), ContractError> { | |
rewards_per_token.iter().for_each(|item| { | |
REWARDS_PER_TOKEN | |
.save(store, &item.0, &Uint128::from(item.1)) | |
.map_err(|_| ContractError::StorageError)?; | |
}); | |
Ok(()) | |
} |
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)
- ADOs/nft-staking/src/execute.rs (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- ADOs/nft-staking/src/execute.rs
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 (2)
- ADOs/nft-staking/src/execute.rs (1 hunks)
- ADOs/nft-staking/src/state.rs (1 hunks)
Files skipped from review as they are similar to previous changes (2)
- ADOs/nft-staking/src/execute.rs
- ADOs/nft-staking/src/state.rs
andromedaprotocol/andromeda-core#505 Looking to resolve the issue with The fix will likely require your error type to support |
I think
This is casting |
Contact Information
Summary: With the Nft Staking ADO, nft holders can stake their nft to gain rewards. With enough incentive for asset holders, it will play an important role to keep the market active and attract more people to create and hold nfts.
This is the solution of #8
Messages:
Instantiate
The ADO creator instantiates the contract with reward denomiation, a list of rewards amount for nft contract address, unbonding period for nfts and the payout window which defines the frequency of the reward distribution.
ExecuteMsg
SendNft
to the Nft Staking ADO.ClaimReward
message with the token address and id they staked.Unstake
with the token address and token id they staked. Once token is unstaked, no rewards will be distributed for that token and user can claim the asset after unbonding periodClaimAsset
message. The token will be transferred back to the userUpdateConfig
message. The applied unbonding period will be applied for future unstaking activity.QueryMsg
Config
Returns configuration for the Nft Staking ADO as
ConfigResponse
.RewardsPerToken
Returns the list of pairs of token price and reward as
RewardsPerTokenResponse
.Stakers
Returns the list of stakers in
StakersResponse
StakerDetail
Returns the list of staked assets and total pending reward for the staker.
assets
is specifying the list of(token_address, token_id)
AssetDetail
Returns the staked asset's detailed information.
Notes
execute_amp_receive
function's return value . That is reported via thiscall_action
before handlingExecuteMsg
. However, it was not suitable tocall_action
for non andromeda-core projects. (When writing an integration test for theSendNft
,call_action
was returningInvalidAddress
error for valid addresses), Ascall_action
is for andromeda-core ADO architecture, like app component -> modules, it was not suitable for custom ADO developmentSummary by CodeRabbit
Summary by CodeRabbit
New Features
Documentation
Tests