difftreelog
test Add test for "sef sponsoring" and "remove sponsor".
in: master
4 files changed
pallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
+++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
@@ -27,8 +27,13 @@
}
}
-// Selector: 06fc42e9
+// Selector: 6073d917
contract ContractHelpers is Dummy, ERC165 {
+ // Get contract ovner
+ //
+ // @param Contract_address contract for which the owner is being determined.
+ // @return Contract owner.
+ //
// Selector: contractOwner(address) 5152b14c
function contractOwner(address contractAddress)
public
@@ -41,6 +46,11 @@
return 0x0000000000000000000000000000000000000000;
}
+ // Set sponsor.
+ //
+ // @param contract_address Contract for which a sponsor is being established.
+ // @param sponsor User address who set as pending sponsor.
+ //
// Selector: setSponsor(address,address) f01fba93
function setSponsor(address contractAddress, address sponsor) public {
require(false, stub_error);
@@ -49,6 +59,34 @@
dummy = 0;
}
+ // Set contract as self sponsored.
+ //
+ // @param contract_address Contract for which a self sponsoring is being enabled.
+ //
+ // Selector: selfSponsoredEnable(address) 89f7d9ae
+ function selfSponsoredEnable(address contractAddress) public {
+ require(false, stub_error);
+ contractAddress;
+ dummy = 0;
+ }
+
+ // Remove sponsor.
+ //
+ // @param contract_address Contract for which a sponsorship is being removed.
+ //
+ // Selector: removeSponsor(address) ef784250
+ function removeSponsor(address contractAddress) public {
+ require(false, stub_error);
+ contractAddress;
+ dummy = 0;
+ }
+
+ // Confirm sponsorship.
+ //
+ // @dev Caller must be same that set via [`set_sponsor`].
+ //
+ // @param contract_address Сontract for which need to confirm sponsorship.
+ //
// Selector: confirmSponsorship(address) abc00001
function confirmSponsorship(address contractAddress) public {
require(false, stub_error);
@@ -56,6 +94,11 @@
dummy = 0;
}
+ // Get current sponsor.
+ //
+ // @param contract_address The contract for which a sponsor is requested.
+ // @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
+ //
// Selector: getSponsor(address) 743fc745
function getSponsor(address contractAddress)
public
@@ -68,6 +111,11 @@
return Tuple0(0x0000000000000000000000000000000000000000, 0);
}
+ // Check tat contract has confirmed sponsor.
+ //
+ // @param contract_address The contract for which the presence of a confirmed sponsor is checked.
+ // @return **true** if contract has confirmed sponsor.
+ //
// Selector: hasSponsor(address) 97418603
function hasSponsor(address contractAddress) public view returns (bool) {
require(false, stub_error);
@@ -76,6 +124,11 @@
return false;
}
+ // Check tat contract has pending sponsor.
+ //
+ // @param contract_address The contract for which the presence of a pending sponsor is checked.
+ // @return **true** if contract has pending sponsor.
+ //
// Selector: hasPendingSponsor(address) 39b9b242
function hasPendingSponsor(address contractAddress)
public
tests/src/eth/api/ContractHelpers.soldiffbeforeafterboth--- a/tests/src/eth/api/ContractHelpers.sol
+++ b/tests/src/eth/api/ContractHelpers.sol
@@ -18,29 +18,74 @@
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
-// Selector: 06fc42e9
+// Selector: 6073d917
interface ContractHelpers is Dummy, ERC165 {
+ // Get contract ovner
+ //
+ // @param Contract_address contract for which the owner is being determined.
+ // @return Contract owner.
+ //
// Selector: contractOwner(address) 5152b14c
function contractOwner(address contractAddress)
external
view
returns (address);
+ // Set sponsor.
+ //
+ // @param contract_address Contract for which a sponsor is being established.
+ // @param sponsor User address who set as pending sponsor.
+ //
// Selector: setSponsor(address,address) f01fba93
function setSponsor(address contractAddress, address sponsor) external;
+ // Set contract as self sponsored.
+ //
+ // @param contract_address Contract for which a self sponsoring is being enabled.
+ //
+ // Selector: selfSponsoredEnable(address) 89f7d9ae
+ function selfSponsoredEnable(address contractAddress) external;
+
+ // Remove sponsor.
+ //
+ // @param contract_address Contract for which a sponsorship is being removed.
+ //
+ // Selector: removeSponsor(address) ef784250
+ function removeSponsor(address contractAddress) external;
+
+ // Confirm sponsorship.
+ //
+ // @dev Caller must be same that set via [`set_sponsor`].
+ //
+ // @param contract_address Сontract for which need to confirm sponsorship.
+ //
// Selector: confirmSponsorship(address) abc00001
function confirmSponsorship(address contractAddress) external;
+ // Get current sponsor.
+ //
+ // @param contract_address The contract for which a sponsor is requested.
+ // @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
+ //
// Selector: getSponsor(address) 743fc745
function getSponsor(address contractAddress)
external
view
returns (Tuple0 memory);
+ // Check tat contract has confirmed sponsor.
+ //
+ // @param contract_address The contract for which the presence of a confirmed sponsor is checked.
+ // @return **true** if contract has confirmed sponsor.
+ //
// Selector: hasSponsor(address) 97418603
function hasSponsor(address contractAddress) external view returns (bool);
+ // Check tat contract has pending sponsor.
+ //
+ // @param contract_address The contract for which the presence of a pending sponsor is checked.
+ // @return **true** if contract has pending sponsor.
+ //
// Selector: hasPendingSponsor(address) 39b9b242
function hasPendingSponsor(address contractAddress)
external
tests/src/eth/contractSponsoring.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 {expect} from 'chai';18import {19 contractHelpers,20 createEthAccountWithBalance,21 transferBalanceToEth,22 deployFlipper,23 itWeb3,24 SponsoringMode,25 createEthAccount,26 ethBalanceViaSub,27} from './util/helpers';28import {evmToAddress} from '@polkadot/util-crypto';2930describe('Sponsoring EVM contracts', () => {31 itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3, privateKeyWrapper}) => {32 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);33 const flipper = await deployFlipper(web3, owner);34 const helpers = contractHelpers(web3, owner);35 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;36 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});37 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;38 });3940 itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {41 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);42 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);43 const flipper = await deployFlipper(web3, owner);44 const helpers = contractHelpers(web3, owner);45 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;46 await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).send({from: notOwner})).to.rejected;47 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;48 });49 50 itWeb3('Sponsor can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {51 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);52 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);53 const flipper = await deployFlipper(web3, owner);54 const helpers = contractHelpers(web3, owner);55 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;56 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;57 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.true;58 });59 60 itWeb3('Sponsor can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {61 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);62 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);63 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);64 const flipper = await deployFlipper(web3, owner);65 const helpers = contractHelpers(web3, owner);66 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;67 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).call({from: notOwner})).to.be.rejectedWith('NoPermission');68 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;69 });7071 itWeb3('Sponsorship can be confirmed by the address that pending as sponsor', async ({api, web3, privateKeyWrapper}) => {72 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);73 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);74 const flipper = await deployFlipper(web3, owner);75 const helpers = contractHelpers(web3, owner);76 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;77 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;78 await expect(helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor})).to.be.not.rejected;79 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;80 });8182 itWeb3('Sponsorship can not be confirmed by the address that not pending as sponsor', async ({api, web3, privateKeyWrapper}) => {83 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);84 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);85 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);86 const flipper = await deployFlipper(web3, owner);87 const helpers = contractHelpers(web3, owner);88 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;89 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;90 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPermission');91 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;92 });9394 itWeb3('Get confirmed sponsor', async ({api, web3, privateKeyWrapper}) => {95 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);96 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);97 const flipper = await deployFlipper(web3, owner);98 const helpers = contractHelpers(web3, owner);99 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();100 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});101 102 const result = await helpers.methods.getSponsor(flipper.options.address).call();103104 expect(result[0]).to.be.eq(sponsor);105 const sponsorSub = api.registry.createType('AccountId', '0x' + BigInt(result[1]).toString(16).padStart(64, '0')).toJSON();106 expect(sponsorSub).to.be.eq(evmToAddress(sponsor));107 });108109 itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {110 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);111 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);112 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);113114 const flipper = await deployFlipper(web3, owner);115116 const helpers = contractHelpers(web3, owner);117118 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;119 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();120 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});121 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;122123 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});124 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});125126 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);127 const callerBalanceBefore = await ethBalanceViaSub(api, caller);128129 await flipper.methods.flip().send({from: caller});130 expect(await flipper.methods.getValue().call()).to.be.true;131132 // Balance should be taken from sponsor instead of caller133 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);134 const callerBalanceAfter = await ethBalanceViaSub(api, caller);135 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;136 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);137 });138139 itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease (allowlisted)', async ({api, web3, privateKeyWrapper}) => {140 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);141 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);142 const caller = createEthAccount(web3);143144 const flipper = await deployFlipper(web3, owner);145146 const helpers = contractHelpers(web3, owner);147 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});148 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});149150 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});151 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});152153 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();154 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});155156 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);157 expect(sponsorBalanceBefore).to.be.not.equal('0');158159 await flipper.methods.flip().send({from: caller});160 expect(await flipper.methods.getValue().call()).to.be.true;161162 // Balance should be taken from flipper instead of caller163 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);164 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;165 });166167 itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should not decrease (non-allowlisted)', async ({api, web3, privateKeyWrapper}) => {168 const alice = privateKeyWrapper('//Alice');169170 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);171 const caller = createEthAccount(web3);172173 const flipper = await deployFlipper(web3, owner);174175 const helpers = contractHelpers(web3, owner);176177 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});178 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});179180 await transferBalanceToEth(api, alice, flipper.options.address);181182 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);183 expect(originalFlipperBalance).to.be.not.equal('0');184185 await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);186 expect(await flipper.methods.getValue().call()).to.be.false;187188 // Balance should be taken from flipper instead of caller189 const balanceAfter = await web3.eth.getBalance(flipper.options.address);190 expect(+balanceAfter).to.be.equals(+originalFlipperBalance);191 });192193 itWeb3('Sponsoring is set, an address that has UNQ can send a transaction and it works. User balance should not change', async ({api, web3, privateKeyWrapper}) => {194 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);195 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);196 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);197198 const flipper = await deployFlipper(web3, owner);199200 const helpers = contractHelpers(web3, owner);201 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});202 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});203204 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});205 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});206207 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();208 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});209210 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);211 const callerBalanceBefore = await ethBalanceViaSub(api, caller);212213 await flipper.methods.flip().send({from: caller});214 expect(await flipper.methods.getValue().call()).to.be.true;215216 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);217 const callerBalanceAfter = await ethBalanceViaSub(api, caller);218 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;219 expect(callerBalanceAfter).to.be.equals(callerBalanceBefore);220 });221222 itWeb3('Sponsoring is limited, with setContractRateLimit. The limitation is working if transactions are sent more often, the sender pays the commission.', async ({api, web3, privateKeyWrapper}) => {223 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);224 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);225 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);226 const originalCallerBalance = await web3.eth.getBalance(caller);227228 const flipper = await deployFlipper(web3, owner);229230 const helpers = contractHelpers(web3, owner);231 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});232 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});233234 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});235 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});236237 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();238 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});239240 const originalFlipperBalance = await web3.eth.getBalance(sponsor);241 expect(originalFlipperBalance).to.be.not.equal('0');242243 await flipper.methods.flip().send({from: caller});244 expect(await flipper.methods.getValue().call()).to.be.true;245 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);246247 const newFlipperBalance = await web3.eth.getBalance(sponsor);248 expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);249250 await flipper.methods.flip().send({from: caller});251 expect(await web3.eth.getBalance(sponsor)).to.be.equal(newFlipperBalance);252 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);253 });254255 // TODO: Find a way to calculate default rate limit256 itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {257 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);258 const flipper = await deployFlipper(web3, owner);259 const helpers = contractHelpers(web3, owner);260 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');261 });262});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 {expect} from 'chai';18import {19 contractHelpers,20 createEthAccountWithBalance,21 transferBalanceToEth,22 deployFlipper,23 itWeb3,24 SponsoringMode,25 createEthAccount,26 ethBalanceViaSub,27} from './util/helpers';28import {evmToAddress} from '@polkadot/util-crypto';2930describe('Sponsoring EVM contracts', () => {31 itWeb3('Self sponsored can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {32 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);33 const flipper = await deployFlipper(web3, owner);34 const helpers = contractHelpers(web3, owner);35 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;36 await expect(helpers.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;37 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;38 });3940 itWeb3('Self sponsored can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {41 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);42 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);43 const flipper = await deployFlipper(web3, owner);44 const helpers = contractHelpers(web3, owner);45 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;46 await expect(helpers.methods.selfSponsoredEnable(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');47 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;48 });4950 itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3, privateKeyWrapper}) => {51 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);52 const flipper = await deployFlipper(web3, owner);53 const helpers = contractHelpers(web3, owner);54 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;55 await expect(helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner})).to.be.not.rejected;56 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;57 });5859 itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {60 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);61 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);62 const flipper = await deployFlipper(web3, owner);63 const helpers = contractHelpers(web3, owner);64 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;65 await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).call({from: notOwner})).to.be.rejectedWith('NoPermission');66 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;67 });68 69 itWeb3('Sponsor can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {70 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);71 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);72 const flipper = await deployFlipper(web3, owner);73 const helpers = contractHelpers(web3, owner);74 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;75 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;76 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.true;77 });78 79 itWeb3('Sponsor can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {80 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);81 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);82 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);83 const flipper = await deployFlipper(web3, owner);84 const helpers = contractHelpers(web3, owner);85 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;86 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).call({from: notOwner})).to.be.rejectedWith('NoPermission');87 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;88 });8990 itWeb3('Sponsorship can be confirmed by the address that pending as sponsor', async ({api, web3, privateKeyWrapper}) => {91 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);92 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);93 const flipper = await deployFlipper(web3, owner);94 const helpers = contractHelpers(web3, owner);95 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;96 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;97 await expect(helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor})).to.be.not.rejected;98 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;99 });100101 itWeb3('Sponsorship can not be confirmed by the address that not pending as sponsor', async ({api, web3, privateKeyWrapper}) => {102 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);103 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);104 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);105 const flipper = await deployFlipper(web3, owner);106 const helpers = contractHelpers(web3, owner);107 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;108 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;109 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPermission');110 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;111 });112113 itWeb3('Get self sponsored sponsor', async ({api, web3, privateKeyWrapper}) => {114 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115 const flipper = await deployFlipper(web3, owner);116 const helpers = contractHelpers(web3, owner);117 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();118 119 const result = await helpers.methods.getSponsor(flipper.options.address).call();120121 expect(result[0]).to.be.eq(flipper.options.address);122 const sponsorSub = api.registry.createType('AccountId', '0x' + BigInt(result[1]).toString(16).padStart(64, '0')).toJSON();123 expect(sponsorSub).to.be.eq(evmToAddress(flipper.options.address));124 });125126 itWeb3('Get confirmed sponsor', async ({api, web3, privateKeyWrapper}) => {127 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);128 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);129 const flipper = await deployFlipper(web3, owner);130 const helpers = contractHelpers(web3, owner);131 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();132 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});133 134 const result = await helpers.methods.getSponsor(flipper.options.address).call();135136 expect(result[0]).to.be.eq(sponsor);137 const sponsorSub = api.registry.createType('AccountId', '0x' + BigInt(result[1]).toString(16).padStart(64, '0')).toJSON();138 expect(sponsorSub).to.be.eq(evmToAddress(sponsor));139 });140141 itWeb3('Sponsor can be removed by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {142 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);143 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);144 const flipper = await deployFlipper(web3, owner);145 const helpers = contractHelpers(web3, owner);146147 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;148 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();149 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});150 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;151 152 await helpers.methods.removeSponsor(flipper.options.address).send();153 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;154 });155156 itWeb3('Sponsor can not be removed by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {157 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);158 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);159 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);160 const flipper = await deployFlipper(web3, owner);161 const helpers = contractHelpers(web3, owner);162163 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;164 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();165 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});166 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;167 168 await expect(helpers.methods.removeSponsor(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');169 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;170 });171172 itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {173 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);174 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);175 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);176177 const flipper = await deployFlipper(web3, owner);178179 const helpers = contractHelpers(web3, owner);180181 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();182 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});183184 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});185 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});186187 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);188 const callerBalanceBefore = await ethBalanceViaSub(api, caller);189190 await flipper.methods.flip().send({from: caller});191 expect(await flipper.methods.getValue().call()).to.be.true;192193 // Balance should be taken from sponsor instead of caller194 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);195 const callerBalanceAfter = await ethBalanceViaSub(api, caller);196 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;197 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);198 });199200 itWeb3('In generous mode, non-allowlisted user transaction will be self sponsored', async ({api, web3, privateKeyWrapper}) => {201 const alice = privateKeyWrapper('//Alice');202203 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);204 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);205206 const flipper = await deployFlipper(web3, owner);207208 const helpers = contractHelpers(web3, owner);209210 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();211212 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});213 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});214215 await transferBalanceToEth(api, alice, flipper.options.address);216217 const contractBalanceBefore = await ethBalanceViaSub(api, flipper.options.address);218 const callerBalanceBefore = await ethBalanceViaSub(api, caller);219220 await flipper.methods.flip().send({from: caller});221 expect(await flipper.methods.getValue().call()).to.be.true;222223 // Balance should be taken from sponsor instead of caller224 const contractBalanceAfter = await ethBalanceViaSub(api, flipper.options.address);225 const callerBalanceAfter = await ethBalanceViaSub(api, caller);226 expect(contractBalanceAfter < contractBalanceBefore).to.be.true;227 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);228 });229230 itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease (allowlisted)', async ({api, web3, privateKeyWrapper}) => {231 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);232 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);233 const caller = createEthAccount(web3);234235 const flipper = await deployFlipper(web3, owner);236237 const helpers = contractHelpers(web3, owner);238 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});239 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});240241 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});242 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});243244 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();245 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});246247 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);248 expect(sponsorBalanceBefore).to.be.not.equal('0');249250 await flipper.methods.flip().send({from: caller});251 expect(await flipper.methods.getValue().call()).to.be.true;252253 // Balance should be taken from flipper instead of caller254 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);255 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;256 });257258 itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should not decrease (non-allowlisted)', async ({api, web3, privateKeyWrapper}) => {259 const alice = privateKeyWrapper('//Alice');260261 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);262 const caller = createEthAccount(web3);263264 const flipper = await deployFlipper(web3, owner);265266 const helpers = contractHelpers(web3, owner);267268 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});269 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});270271 await transferBalanceToEth(api, alice, flipper.options.address);272273 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);274 expect(originalFlipperBalance).to.be.not.equal('0');275276 await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);277 expect(await flipper.methods.getValue().call()).to.be.false;278279 // Balance should be taken from flipper instead of caller280 const balanceAfter = await web3.eth.getBalance(flipper.options.address);281 expect(+balanceAfter).to.be.equals(+originalFlipperBalance);282 });283284 itWeb3('Sponsoring is set, an address that has UNQ can send a transaction and it works. User balance should not change', async ({api, web3, privateKeyWrapper}) => {285 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);286 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);287 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);288289 const flipper = await deployFlipper(web3, owner);290291 const helpers = contractHelpers(web3, owner);292 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});293 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});294295 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});296 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});297298 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();299 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});300301 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);302 const callerBalanceBefore = await ethBalanceViaSub(api, caller);303304 await flipper.methods.flip().send({from: caller});305 expect(await flipper.methods.getValue().call()).to.be.true;306307 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);308 const callerBalanceAfter = await ethBalanceViaSub(api, caller);309 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;310 expect(callerBalanceAfter).to.be.equals(callerBalanceBefore);311 });312313 itWeb3('Sponsoring is limited, with setContractRateLimit. The limitation is working if transactions are sent more often, the sender pays the commission.', async ({api, web3, privateKeyWrapper}) => {314 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);315 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);316 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);317 const originalCallerBalance = await web3.eth.getBalance(caller);318319 const flipper = await deployFlipper(web3, owner);320321 const helpers = contractHelpers(web3, owner);322 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});323 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});324325 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});326 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});327328 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();329 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});330331 const originalFlipperBalance = await web3.eth.getBalance(sponsor);332 expect(originalFlipperBalance).to.be.not.equal('0');333334 await flipper.methods.flip().send({from: caller});335 expect(await flipper.methods.getValue().call()).to.be.true;336 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);337338 const newFlipperBalance = await web3.eth.getBalance(sponsor);339 expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);340341 await flipper.methods.flip().send({from: caller});342 expect(await web3.eth.getBalance(sponsor)).to.be.equal(newFlipperBalance);343 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);344 });345346 // TODO: Find a way to calculate default rate limit347 itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {348 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);349 const flipper = await deployFlipper(web3, owner);350 const helpers = contractHelpers(web3, owner);351 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');352 });353});tests/src/eth/util/contractHelpersAbi.jsondiffbeforeafterboth--- a/tests/src/eth/util/contractHelpersAbi.json
+++ b/tests/src/eth/util/contractHelpersAbi.json
@@ -120,6 +120,32 @@
"internalType": "address",
"name": "contractAddress",
"type": "address"
+ }
+ ],
+ "name": "removeSponsor",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ }
+ ],
+ "name": "selfSponsoredEnable",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
},
{ "internalType": "address", "name": "sponsor", "type": "address" }
],