From da6ca884c38d99e0dd2c23beb8531bb1c0ebc1bb Mon Sep 17 00:00:00 2001
From: Xiliang Chen <xlchen1291@gmail.com>
Date: Sat, 24 Oct 2020 10:56:48 +1300
Subject: [PATCH] handle self transfer better (#307)

---
 nft/src/lib.rs   | 16 +++++++++++-----
 nft/src/tests.rs |  5 +++++
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/nft/src/lib.rs b/nft/src/lib.rs
index 06bdf6b..da8804f 100644
--- a/nft/src/lib.rs
+++ b/nft/src/lib.rs
@@ -141,12 +141,14 @@ impl<T: Trait> Module<T> {
 
 	/// Transfer NFT(non fungible token) from `from` account to `to` account
 	pub fn transfer(from: &T::AccountId, to: &T::AccountId, token: (T::ClassId, T::TokenId)) -> DispatchResult {
-		if from == to {
-			return Ok(());
-		}
-
 		TokensByOwner::<T>::try_mutate_exists(from, token, |token_by_owner| -> DispatchResult {
-			ensure!(token_by_owner.take().is_some(), Error::<T>::NoPermission);
+			ensure!(token_by_owner.is_some(), Error::<T>::NoPermission);
+			if from == to {
+				// no change needed
+				return Ok(());
+			}
+
+			*token_by_owner = None;
 			TokensByOwner::<T>::insert(to, token, ());
 
 			Tokens::<T>::try_mutate_exists(token.0, token.1, |token_info| -> DispatchResult {
@@ -218,4 +220,8 @@ impl<T: Trait> Module<T> {
 			Ok(())
 		})
 	}
+
+	pub fn is_owner(account: &T::AccountId, token: (T::ClassId, T::TokenId)) -> bool {
+		TokensByOwner::<T>::contains_key(account, token)
+	}
 }
diff --git a/nft/src/tests.rs b/nft/src/tests.rs
index 81187b7..a241921 100644
--- a/nft/src/tests.rs
+++ b/nft/src/tests.rs
@@ -62,6 +62,7 @@ fn transfer_should_work() {
 		assert_ok!(NonFungibleTokenModule::transfer(&BOB, &BOB, (CLASS_ID, TOKEN_ID)));
 		assert_ok!(NonFungibleTokenModule::transfer(&BOB, &ALICE, (CLASS_ID, TOKEN_ID)));
 		assert_ok!(NonFungibleTokenModule::transfer(&ALICE, &BOB, (CLASS_ID, TOKEN_ID)));
+		assert!(NonFungibleTokenModule::is_owner(&BOB, (CLASS_ID, TOKEN_ID)));
 	});
 }
 
@@ -82,6 +83,10 @@ fn transfer_should_fail() {
 			NonFungibleTokenModule::mint(&BOB, CLASS_ID_NOT_EXIST, vec![1], ()),
 			Error::<Runtime>::ClassNotFound
 		);
+		assert_noop!(
+			NonFungibleTokenModule::transfer(&ALICE, &ALICE, (CLASS_ID, TOKEN_ID)),
+			Error::<Runtime>::NoPermission
+		);
 	});
 }
 
-- 
GitLab