Skip to content
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

Initial RMRK Market pallet skeleton #65

Merged
merged 14 commits into from
Feb 1, 2022

Conversation

HashWarlock
Copy link
Contributor

@HashWarlock HashWarlock commented Jan 24, 2022

Targets

  • Create folder for Market pallet
  • Update naming to rmrk-market
  • Build out the Market pallet skeleton structure
  • Implement list and buy with tests
  • Implement unlist with tests
  • Implement offer, accept_offer and withdraw_offer with tests
  • Clean up warnings

Procedure

  • Create folder for Market Pallet with README.md similar to the description in issue Market pallet design #59
  • Build skeleton structure of the Market Pallet Cargo.toml, src/lib.rs, src/mock.rs, src/tests.rs
  • Implement functions list and buy with unit tests that omit the royalties logic first

RMRK Spec

@HashWarlock
Copy link
Contributor Author

HashWarlock commented Jan 31, 2022

Added a test scenario that needs to be addressed in code:

  1. Alice mints & lists NFT [0,0] for price X
  2. Alice sends NFT [0,0] to Charlie
  3. Bob purchases NFT [0,0] at price X and the transaction goes through

To prevent this, we need to have a type name ListInfo that will map the listing to the original account that listed the NFT & when a buy is executed in the scenario above, the transaction will not go through & remove the ListInfo from storage.

Or would this be better handled by UI dapp?

… to ensure NFTs cannot be bought after transferred or if a listing has expired
@HashWarlock HashWarlock requested a review from ilionic January 31, 2022 06:48
@HashWarlock HashWarlock marked this pull request as draft January 31, 2022 17:44
Copy link
Contributor

@ilionic ilionic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
Essential interactions work correctly, MinimumOfferAmount probably could be smaller amount. Also please check clippy warnings.

@HashWarlock HashWarlock marked this pull request as ready for review February 1, 2022 22:06
@ilionic ilionic merged commit a395e31 into rmrk-team:main Feb 1, 2022
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// The price for a token was updated \[owner, collection_id, nft_id, price\]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary to leave the param names in the docstring. The field names in the structure enum variant are already self-explained.

}

parameter_types! {
pub ClassBondAmount: Balance = 100;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in use?

collection_id: CollectionId,
nft_id: NftId,
) -> DispatchResult {
let sender = ensure_signed(origin.clone())?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary to call .clone() here?

// Ensure that the NFT is not owned by an NFT
ensure!(!Self::is_nft_owned_by_nft(collection_id, nft_id),
Error::<T>::CannotListNftOwnedByNft);
// Ensure sender is not the owner
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure sender is the owner

}

// Add new ListInfo with listed_by, amount, Option<BlockNumber>
ListedNfts::<T>::insert(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we lock the NFT after listing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Wouldn't this prevent the NFT from being bought? Or do you think it would be best to unlock the NFT when a buy is initiated.

},
);
// Reserve currency from offerer account
<T as pallet::Config>::Currency::reserve(&sender, amount)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good habit to do all the checks before making any change to the state. So I'd suggest to move the reserve action before making the change to Offers.

In Substrate, if we don't have transactional modifier, all the changes to the state will take place immediately. If if the function fails later, the changes are still applied. Although we do have transactional here, I think it's still good to always follow the best practice whenever possible.

Comment on lines +373 to +376
ensure!(sender == owner || sender == offer.maker, Error::<T>::CannotWithdrawOffer);

// Unreserve currency from offerer account
<T as pallet::Config>::Currency::unreserve(&sender, offer.amount);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like if the NFT owner withdrew the offer, he can rob the reserved money

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, need to change this to offer.maker

HashWarlock added a commit to HashWarlock/rmrk-substrate that referenced this pull request Feb 13, 2022
@HashWarlock HashWarlock deleted the feat/market-pallet branch March 3, 2022 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants