difftreelog
added repartition method to refungible erc20 extensions
in: master
7 files changed
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -1,3 +1,19 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
extern crate alloc;
use evm_coder::{generate_stubgen, solidity_interface, types::*};
pallets/refungible/src/erc_token.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -149,6 +149,15 @@
.map_err(dispatch_to_evm::<T>)?;
Ok(true)
}
+
+ #[weight(<SelfWeightOf<T>>::repartition_item())]
+ fn repartition(&mut self, caller: caller, amount: uint256) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
+
+ <Pallet<T>>::repartition(self, &caller, self.1, amount).map_err(dispatch_to_evm::<T>)?;
+ Ok(true)
+ }
}
impl<T: Config> RefungibleTokenHandle<T> {
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
@@ -31,18 +31,6 @@
);
}
-// Selector: 79cc6790
-contract ERC20UniqueExtensions is Dummy, ERC165 {
- // Selector: burnFrom(address,uint256) 79cc6790
- function burnFrom(address from, uint256 amount) public returns (bool) {
- require(false, stub_error);
- from;
- amount;
- dummy = 0;
- return false;
- }
-}
-
// Selector: 942e8b22
contract ERC20 is Dummy, ERC165, ERC20Events {
// Selector: name() 06fdde03
@@ -127,4 +115,24 @@
}
}
+// Selector: ab8deb37
+contract ERC20UniqueExtensions is Dummy, ERC165 {
+ // Selector: burnFrom(address,uint256) 79cc6790
+ function burnFrom(address from, uint256 amount) public returns (bool) {
+ require(false, stub_error);
+ from;
+ amount;
+ dummy = 0;
+ return false;
+ }
+
+ // Selector: repartition(uint256) d2418ca7
+ function repartition(uint256 amount) public returns (bool) {
+ require(false, stub_error);
+ amount;
+ dummy = 0;
+ return false;
+ }
+}
+
contract UniqueRefungibleToken is Dummy, ERC165, ERC20, ERC20UniqueExtensions {}
tests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungibleToken.sol
+++ b/tests/src/eth/api/UniqueRefungibleToken.sol
@@ -22,12 +22,6 @@
);
}
-// Selector: 79cc6790
-interface ERC20UniqueExtensions is Dummy, ERC165 {
- // Selector: burnFrom(address,uint256) 79cc6790
- function burnFrom(address from, uint256 amount) external returns (bool);
-}
-
// Selector: 942e8b22
interface ERC20 is Dummy, ERC165, ERC20Events {
// Selector: name() 06fdde03
@@ -65,6 +59,15 @@
returns (uint256);
}
+// Selector: ab8deb37
+interface ERC20UniqueExtensions is Dummy, ERC165 {
+ // Selector: burnFrom(address,uint256) 79cc6790
+ function burnFrom(address from, uint256 amount) external returns (bool);
+
+ // Selector: repartition(uint256) d2418ca7
+ function repartition(uint256 amount) external returns (bool);
+}
+
interface UniqueRefungibleToken is
Dummy,
ERC165,
tests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';18import {createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';2021import chai from 'chai';22import chaiAsPromised from 'chai-as-promised';23chai.use(chaiAsPromised);24const expect = chai.expect;2526describe('Refungible token: Information getting', () => {27 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {28 const alice = privateKeyWrapper('//Alice');2930 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;3132 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);3334 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;3536 const address = tokenIdToAddress(collectionId, tokenId);37 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});38 const totalSupply = await contract.methods.totalSupply().call();3940 expect(totalSupply).to.equal('200');41 });4243 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {44 const alice = privateKeyWrapper('//Alice');4546 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;4748 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);4950 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;5152 const address = tokenIdToAddress(collectionId, tokenId);53 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});54 const balance = await contract.methods.balanceOf(caller).call();5556 expect(balance).to.equal('200');57 });5859 itWeb3('decimals', async ({api, web3, privateKeyWrapper}) => {60 const alice = privateKeyWrapper('//Alice');6162 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;6364 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);6566 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;6768 const address = tokenIdToAddress(collectionId, tokenId);69 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});70 const decimals = await contract.methods.decimals().call();7172 expect(decimals).to.equal('0');73 });74});7576describe('Refungible: Plain calls', () => {77 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {78 const alice = privateKeyWrapper('//Alice');7980 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;8182 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);8384 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;8586 const address = tokenIdToAddress(collectionId, tokenId);8788 const spender = createEthAccount(web3);8990 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});9192 {93 const result = await contract.methods.approve(spender, 100).send({from: owner});94 const events = normalizeEvents(result.events);9596 expect(events).to.be.deep.equal([97 {98 address,99 event: 'Approval',100 args: {101 owner,102 spender,103 value: '100',104 },105 },106 ]);107 }108109 {110 const allowance = await contract.methods.allowance(owner, spender).call();111 expect(+allowance).to.equal(100);112 }113 });114115 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {116 const alice = privateKeyWrapper('//Alice');117118 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;119120 const owner = createEthAccount(web3);121 await transferBalanceToEth(api, alice, owner);122123 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;124125 const spender = createEthAccount(web3);126 await transferBalanceToEth(api, alice, spender);127128 const receiver = createEthAccount(web3);129130 const address = tokenIdToAddress(collectionId, tokenId);131 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});132133 await contract.methods.approve(spender, 100).send();134135 {136 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});137 const events = normalizeEvents(result.events);138 expect(events).to.be.deep.equal([139 {140 address,141 event: 'Transfer',142 args: {143 from: owner,144 to: receiver,145 value: '49',146 },147 },148 {149 address,150 event: 'Approval',151 args: {152 owner,153 spender,154 value: '51',155 },156 },157 ]);158 }159160 {161 const balance = await contract.methods.balanceOf(receiver).call();162 expect(+balance).to.equal(49);163 }164165 {166 const balance = await contract.methods.balanceOf(owner).call();167 expect(+balance).to.equal(151);168 }169 });170171 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {172 const alice = privateKeyWrapper('//Alice');173174 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;175176 const owner = createEthAccount(web3);177 await transferBalanceToEth(api, alice, owner);178179 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;180181 const receiver = createEthAccount(web3);182 await transferBalanceToEth(api, alice, receiver);183184 const address = tokenIdToAddress(collectionId, tokenId);185 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});186187 {188 const result = await contract.methods.transfer(receiver, 50).send({from: owner});189 const events = normalizeEvents(result.events);190 expect(events).to.be.deep.equal([191 {192 address,193 event: 'Transfer',194 args: {195 from: owner,196 to: receiver,197 value: '50',198 },199 },200 ]);201 }202203 {204 const balance = await contract.methods.balanceOf(owner).call();205 expect(+balance).to.equal(150);206 }207208 {209 const balance = await contract.methods.balanceOf(receiver).call();210 expect(+balance).to.equal(50);211 }212 });213});214215describe('Refungible: Fees', () => {216 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {217 const alice = privateKeyWrapper('//Alice');218219 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;220221 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);222 const spender = createEthAccount(web3);223224 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;225226 const address = tokenIdToAddress(collectionId, tokenId);227 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});228229 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));230 expect(cost < BigInt(0.2 * Number(UNIQUE)));231 });232233 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {234 const alice = privateKeyWrapper('//Alice');235236 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;237238 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);239 const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);240241 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;242243 const address = tokenIdToAddress(collectionId, tokenId);244 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});245246 await contract.methods.approve(spender, 100).send({from: owner});247248 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));249 expect(cost < BigInt(0.2 * Number(UNIQUE)));250 });251252 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {253 const alice = privateKeyWrapper('//Alice');254255 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;256257 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);258 const receiver = createEthAccount(web3);259260 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;261262 const address = tokenIdToAddress(collectionId, tokenId);263 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});264265 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));266 expect(cost < BigInt(0.2 * Number(UNIQUE)));267 });268});269270describe('Refungible: Substrate calls', () => {271 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {272 const alice = privateKeyWrapper('//Alice');273274 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;275276 const receiver = createEthAccount(web3);277278 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;279280 const address = tokenIdToAddress(collectionId, tokenId);281 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);282283 const events = await recordEvents(contract, async () => {284 expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;285 });286287 expect(events).to.be.deep.equal([288 {289 address,290 event: 'Approval',291 args: {292 owner: subToEth(alice.address),293 spender: receiver,294 value: '100',295 },296 },297 ]);298 });299300 itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {301 const alice = privateKeyWrapper('//Alice');302303 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;304 const bob = privateKeyWrapper('//Bob');305306 const receiver = createEthAccount(web3);307308 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;309 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;310311 const address = tokenIdToAddress(collectionId, tokenId);312 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);313314 const events = await recordEvents(contract, async () => {315 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;316 });317318 expect(events).to.be.deep.equal([319 {320 address,321 event: 'Transfer',322 args: {323 from: subToEth(alice.address),324 to: receiver,325 value: '51',326 },327 },328 {329 address,330 event: 'Approval',331 args: {332 owner: subToEth(alice.address),333 spender: subToEth(bob.address),334 value: '49',335 },336 },337 ]);338 });339340 itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {341 const alice = privateKeyWrapper('//Alice');342343 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;344345 const receiver = createEthAccount(web3);346347 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;348349 const address = tokenIdToAddress(collectionId, tokenId);350 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);351352 const events = await recordEvents(contract, async () => {353 expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;354 });355356 expect(events).to.be.deep.equal([357 {358 address,359 event: 'Transfer',360 args: {361 from: subToEth(alice.address),362 to: receiver,363 value: '51',364 },365 },366 ]);367 });368});1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';18import {createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';2021import chai from 'chai';22import chaiAsPromised from 'chai-as-promised';23chai.use(chaiAsPromised);24const expect = chai.expect;2526describe('Refungible token: Information getting', () => {27 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {28 const alice = privateKeyWrapper('//Alice');2930 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;3132 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);3334 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;3536 const address = tokenIdToAddress(collectionId, tokenId);37 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});38 const totalSupply = await contract.methods.totalSupply().call();3940 expect(totalSupply).to.equal('200');41 });4243 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {44 const alice = privateKeyWrapper('//Alice');4546 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;4748 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);4950 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;5152 const address = tokenIdToAddress(collectionId, tokenId);53 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});54 const balance = await contract.methods.balanceOf(caller).call();5556 expect(balance).to.equal('200');57 });5859 itWeb3('decimals', async ({api, web3, privateKeyWrapper}) => {60 const alice = privateKeyWrapper('//Alice');6162 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;6364 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);6566 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;6768 const address = tokenIdToAddress(collectionId, tokenId);69 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});70 const decimals = await contract.methods.decimals().call();7172 expect(decimals).to.equal('0');73 });74});7576describe('Refungible: Plain calls', () => {77 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {78 const alice = privateKeyWrapper('//Alice');7980 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;8182 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);8384 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;8586 const address = tokenIdToAddress(collectionId, tokenId);8788 const spender = createEthAccount(web3);8990 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});9192 {93 const result = await contract.methods.approve(spender, 100).send({from: owner});94 const events = normalizeEvents(result.events);9596 expect(events).to.be.deep.equal([97 {98 address,99 event: 'Approval',100 args: {101 owner,102 spender,103 value: '100',104 },105 },106 ]);107 }108109 {110 const allowance = await contract.methods.allowance(owner, spender).call();111 expect(+allowance).to.equal(100);112 }113 });114115 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {116 const alice = privateKeyWrapper('//Alice');117118 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;119120 const owner = createEthAccount(web3);121 await transferBalanceToEth(api, alice, owner);122123 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;124125 const spender = createEthAccount(web3);126 await transferBalanceToEth(api, alice, spender);127128 const receiver = createEthAccount(web3);129130 const address = tokenIdToAddress(collectionId, tokenId);131 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});132133 await contract.methods.approve(spender, 100).send();134135 {136 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});137 const events = normalizeEvents(result.events);138 expect(events).to.be.deep.equal([139 {140 address,141 event: 'Transfer',142 args: {143 from: owner,144 to: receiver,145 value: '49',146 },147 },148 {149 address,150 event: 'Approval',151 args: {152 owner,153 spender,154 value: '51',155 },156 },157 ]);158 }159160 {161 const balance = await contract.methods.balanceOf(receiver).call();162 expect(+balance).to.equal(49);163 }164165 {166 const balance = await contract.methods.balanceOf(owner).call();167 expect(+balance).to.equal(151);168 }169 });170171 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {172 const alice = privateKeyWrapper('//Alice');173174 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;175176 const owner = createEthAccount(web3);177 await transferBalanceToEth(api, alice, owner);178179 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;180181 const receiver = createEthAccount(web3);182 await transferBalanceToEth(api, alice, receiver);183184 const address = tokenIdToAddress(collectionId, tokenId);185 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});186187 {188 const result = await contract.methods.transfer(receiver, 50).send({from: owner});189 const events = normalizeEvents(result.events);190 expect(events).to.be.deep.equal([191 {192 address,193 event: 'Transfer',194 args: {195 from: owner,196 to: receiver,197 value: '50',198 },199 },200 ]);201 }202203 {204 const balance = await contract.methods.balanceOf(owner).call();205 expect(+balance).to.equal(150);206 }207208 {209 const balance = await contract.methods.balanceOf(receiver).call();210 expect(+balance).to.equal(50);211 }212 });213214 itWeb3('Can perform repartition()', async ({web3, api, privateKeyWrapper}) => {215 const alice = privateKeyWrapper('//Alice');216217 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;218219 const owner = createEthAccount(web3);220 await transferBalanceToEth(api, alice, owner);221222 const receiver = createEthAccount(web3);223 await transferBalanceToEth(api, alice, receiver);224225 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;226227 const address = tokenIdToAddress(collectionId, tokenId);228 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});229230 await contract.methods.repartition(200).send({from: owner});231 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);232 await contract.methods.transfer(receiver, 110).send({from: owner});233 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);234 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);235 236 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;237238 await contract.methods.transfer(receiver, 90).send({from: owner});239 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);240 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);241242 await contract.methods.repartition(150).send({from: receiver});243 await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected;244 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);245 });246});247248describe('Refungible: Fees', () => {249 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {250 const alice = privateKeyWrapper('//Alice');251252 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;253254 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);255 const spender = createEthAccount(web3);256257 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;258259 const address = tokenIdToAddress(collectionId, tokenId);260 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});261262 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));263 expect(cost < BigInt(0.2 * Number(UNIQUE)));264 });265266 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {267 const alice = privateKeyWrapper('//Alice');268269 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;270271 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);272 const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);273274 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;275276 const address = tokenIdToAddress(collectionId, tokenId);277 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});278279 await contract.methods.approve(spender, 100).send({from: owner});280281 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));282 expect(cost < BigInt(0.2 * Number(UNIQUE)));283 });284285 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {286 const alice = privateKeyWrapper('//Alice');287288 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;289290 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);291 const receiver = createEthAccount(web3);292293 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;294295 const address = tokenIdToAddress(collectionId, tokenId);296 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});297298 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));299 expect(cost < BigInt(0.2 * Number(UNIQUE)));300 });301});302303describe('Refungible: Substrate calls', () => {304 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {305 const alice = privateKeyWrapper('//Alice');306307 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;308309 const receiver = createEthAccount(web3);310311 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;312313 const address = tokenIdToAddress(collectionId, tokenId);314 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);315316 const events = await recordEvents(contract, async () => {317 expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;318 });319320 expect(events).to.be.deep.equal([321 {322 address,323 event: 'Approval',324 args: {325 owner: subToEth(alice.address),326 spender: receiver,327 value: '100',328 },329 },330 ]);331 });332333 itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {334 const alice = privateKeyWrapper('//Alice');335336 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;337 const bob = privateKeyWrapper('//Bob');338339 const receiver = createEthAccount(web3);340341 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;342 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;343344 const address = tokenIdToAddress(collectionId, tokenId);345 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);346347 const events = await recordEvents(contract, async () => {348 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;349 });350351 expect(events).to.be.deep.equal([352 {353 address,354 event: 'Transfer',355 args: {356 from: subToEth(alice.address),357 to: receiver,358 value: '51',359 },360 },361 {362 address,363 event: 'Approval',364 args: {365 owner: subToEth(alice.address),366 spender: subToEth(bob.address),367 value: '49',368 },369 },370 ]);371 });372373 itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {374 const alice = privateKeyWrapper('//Alice');375376 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;377378 const receiver = createEthAccount(web3);379380 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;381382 const address = tokenIdToAddress(collectionId, tokenId);383 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);384385 const events = await recordEvents(contract, async () => {386 expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;387 });388389 expect(events).to.be.deep.equal([390 {391 address,392 event: 'Transfer',393 args: {394 from: subToEth(alice.address),395 to: receiver,396 value: '51',397 },398 },399 ]);400 });401});tests/src/eth/reFungibleTokenAbi.jsondiffbeforeafterboth--- a/tests/src/eth/reFungibleTokenAbi.json
+++ b/tests/src/eth/reFungibleTokenAbi.json
@@ -104,6 +104,15 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "amount", "type": "uint256" }
+ ],
+ "name": "repartition",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
],
"name": "supportsInterface",