git.delta.rocks / unique-network / refs/commits / 9d3564ef2b56

difftreelog

chore add transfer event for `burn` and `create_multiple_items`

Grigoriy Simonov2022-08-03parent: #bb6d71b.patch.diff
in: master

3 files changed

modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -399,6 +399,7 @@
 
 	pub fn burn_token_unchecked(
 		collection: &RefungibleHandle<T>,
+		owner: &T::CrossAccountId,
 		token_id: TokenId,
 	) -> DispatchResult {
 		let burnt = <TokensBurnt<T>>::get(collection.id)
@@ -411,7 +412,15 @@
 		<TotalSupply<T>>::remove((collection.id, token_id));
 		<Balance<T>>::remove_prefix((collection.id, token_id), None);
 		<Allowance<T>>::remove_prefix((collection.id, token_id), None);
-		// TODO: ERC721 transfer event
+
+		<PalletEvm<T>>::deposit_log(
+			ERC721Events::Transfer {
+				from: *owner.as_eth(),
+				to: H160::default(),
+				token_id: token_id.into(),
+			}
+			.to_log(collection_id_to_address(collection.id)),
+		);
 		Ok(())
 	}
 
@@ -453,12 +462,12 @@
 			<Owned<T>>::remove((collection.id, owner, token));
 			<PalletStructure<T>>::unnest_if_nested(owner, collection.id, token);
 			<AccountBalance<T>>::insert((collection.id, owner), account_balance);
-			Self::burn_token_unchecked(collection, token)?;
+			Self::burn_token_unchecked(collection, owner, token)?;
 			<PalletEvm<T>>::deposit_log(
-				ERC721Events::Transfer {
+				ERC20Events::Transfer {
 					from: *owner.as_eth(),
 					to: H160::default(),
-					token_id: token.into(),
+					value: amount.into(),
 				}
 				.to_log(collection_id_to_address(collection.id)),
 			);
@@ -490,6 +499,17 @@
 			<PalletStructure<T>>::unnest_if_nested(owner, collection.id, token);
 			<Balance<T>>::remove((collection.id, token, owner));
 			<AccountBalance<T>>::insert((collection.id, owner), account_balance);
+
+			if let Some(user) = Self::token_owner(collection.id, token) {
+				<PalletEvm<T>>::deposit_log(
+					ERC721Events::Transfer {
+						from: erc::ADDRESS_FOR_PARTIALLY_OWNED_TOKENS,
+						to: *user.as_eth(),
+						token_id: token.into(),
+					}
+					.to_log(collection_id_to_address(collection.id)),
+				);
+			}
 		} else {
 			<Balance<T>>::insert((collection.id, token, owner), balance);
 		}
@@ -981,30 +1001,46 @@
 		for (i, token) in data.into_iter().enumerate() {
 			let token_id = first_token_id + i as u32 + 1;
 
-			for (user, amount) in token.users.into_iter() {
-				if amount == 0 {
-					continue;
-				}
+			let receivers = token
+				.users
+				.into_iter()
+				.filter(|(_, amount)| *amount > 0)
+				.collect::<Vec<_>>();
 
+			if let [(user, _)] = receivers.as_slice() {
+				// if there is exactly one receiver
 				<PalletEvm<T>>::deposit_log(
-					ERC20Events::Transfer {
+					ERC721Events::Transfer {
 						from: H160::default(),
 						to: *user.as_eth(),
-						value: amount.into(),
+						token_id: token_id.into(),
 					}
-					.to_log(T::EvmTokenAddressMapping::token_to_address(
-						collection.id,
-						TokenId(token_id),
-					)),
+					.to_log(collection_id_to_address(collection.id)),
 				);
+			} else if let [_, ..] = receivers.as_slice() {
+				// if there is more than one receiver
 				<PalletEvm<T>>::deposit_log(
 					ERC721Events::Transfer {
 						from: H160::default(),
-						to: *user.as_eth(),
+						to: erc::ADDRESS_FOR_PARTIALLY_OWNED_TOKENS,
 						token_id: token_id.into(),
 					}
 					.to_log(collection_id_to_address(collection.id)),
 				);
+			}
+
+			for (user, amount) in receivers.into_iter() {
+				<PalletEvm<T>>::deposit_log(
+					ERC20Events::Transfer {
+						from: H160::default(),
+						to: *user.as_eth(),
+						value: amount.into(),
+					}
+					.to_log(T::EvmTokenAddressMapping::token_to_address(
+						collection.id,
+						TokenId(token_id),
+					)),
+				);
 				<PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(
 					collection.id,
 					TokenId(token_id),
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {createCollectionExpectSuccess, transfer, UNIQUE} from '../util/helpers';17import {createCollectionExpectSuccess, transfer, UNIQUE} from '../util/helpers';
18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, tokenIdToAddress} from './util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress} from './util/helpers';
19import reFungibleAbi from './reFungibleAbi.json';19import reFungibleAbi from './reFungibleAbi.json';
20import reFungibleTokenAbi from './reFungibleTokenAbi.json';20import reFungibleTokenAbi from './reFungibleTokenAbi.json';
21import {expect} from 'chai';21import {expect} from 'chai';
225 const result = await contract.methods.burn(tokenId).send();225 const result = await contract.methods.burn(tokenId).send();
226 const events = normalizeEvents(result.events);226 const events = normalizeEvents(result.events);
227
228 expect(events).to.be.deep.equal([227 expect(events).to.include.deep.members([
229 {228 {
230 address: collectionIdAddress,229 address: collectionIdAddress,
231 event: 'Transfer',230 event: 'Transfer',
333 await tokenContract.methods.repartition(2).send();332 await tokenContract.methods.repartition(2).send();
334 await tokenContract.methods.transfer(receiver, 1).send();333 await tokenContract.methods.transfer(receiver, 1).send();
335334
336 let transfer;335 const events = await recordEvents(contract, async () =>
337 contract.events.Transfer({}, function(_error: any, event: any){ transfer = event;});
338 await tokenContract.methods.transfer(receiver, 1).send();336 await tokenContract.methods.transfer(receiver, 1).send());
339 const events = normalizeEvents([transfer]);
340 expect(events).to.deep.equal([337 expect(events).to.deep.equal([
341 {338 {
342 address: collectionIdAddress,339 address: collectionIdAddress,
366363
367 await tokenContract.methods.repartition(2).send();364 await tokenContract.methods.repartition(2).send();
368 365
369 let transfer;366 const events = await recordEvents(contract, async () =>
370 contract.events.Transfer({}, function(_error: any, event: any){ transfer = event;});
371 await tokenContract.methods.transfer(receiver, 1).send();367 await tokenContract.methods.transfer(receiver, 1).send());
372368
373 const events = normalizeEvents([transfer]);
374 expect(events).to.deep.equal([369 expect(events).to.deep.equal([
375 {370 {
376 address: collectionIdAddress,371 address: collectionIdAddress,
modifiedtests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth
--- a/tests/src/eth/reFungibleToken.test.ts
+++ b/tests/src/eth/reFungibleToken.test.ts
@@ -277,7 +277,7 @@
     {
       const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});
       const events = normalizeEvents(result.events);
-      expect(events).to.be.deep.equal([
+      expect(events).to.include.deep.members([
         {
           address,
           event: 'Transfer',
@@ -329,7 +329,7 @@
     {
       const result = await contract.methods.transfer(receiver, 50).send({from: owner});
       const events = normalizeEvents(result.events);
-      expect(events).to.be.deep.equal([
+      expect(events).to.include.deep.members([
         {
           address,
           event: 'Transfer',
@@ -442,6 +442,38 @@
       },
     ]);
   });
+
+  itWeb3('Receiving Transfer event on burning into full ownership', async ({web3, api, privateKeyWrapper}) => {
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const helper = evmCollectionHelpers(web3, caller);
+    const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();
+    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
+    const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+
+    const tokenId = await contract.methods.nextTokenId().call();
+    await contract.methods.mint(caller, tokenId).send();
+
+    const address = tokenIdToAddress(collectionId, tokenId);
+
+    const tokenContract =  new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});
+    await tokenContract.methods.repartition(2).send();
+    await tokenContract.methods.transfer(receiver, 1).send();
+
+    const events =  await recordEvents(contract, async () => 
+      await tokenContract.methods.burnFrom(caller, 1).send());
+    expect(events).to.deep.equal([
+      {
+        address: collectionIdAddress,
+        event: 'Transfer',
+        args: {
+          from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',
+          to: receiver,
+          tokenId,
+        },
+      },
+    ]);
+  });
 });
 
 describe('Refungible: Fees', () => {