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});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" }
],