difftreelog
fix Return sponsor address in canonical form.
in: master
4 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2345,7 +2345,7 @@
[[package]]
name = "fc-consensus"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"async-trait",
"fc-db",
@@ -2364,7 +2364,7 @@
[[package]]
name = "fc-db"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"fp-storage",
"kvdb-rocksdb",
@@ -2380,7 +2380,7 @@
[[package]]
name = "fc-mapping-sync"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"fc-db",
"fp-consensus",
@@ -2397,7 +2397,7 @@
[[package]]
name = "fc-rpc"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"ethereum",
"ethereum-types",
@@ -2437,7 +2437,7 @@
[[package]]
name = "fc-rpc-core"
version = "1.1.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"ethereum",
"ethereum-types",
@@ -2578,7 +2578,7 @@
[[package]]
name = "fp-consensus"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"ethereum",
"parity-scale-codec 3.1.5",
@@ -2590,7 +2590,7 @@
[[package]]
name = "fp-evm"
version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"evm",
"frame-support",
@@ -2604,7 +2604,7 @@
[[package]]
name = "fp-evm-mapping"
version = "0.1.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"frame-support",
"sp-core",
@@ -2613,7 +2613,7 @@
[[package]]
name = "fp-rpc"
version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"ethereum",
"ethereum-types",
@@ -2630,7 +2630,7 @@
[[package]]
name = "fp-self-contained"
version = "1.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"ethereum",
"frame-support",
@@ -2646,7 +2646,7 @@
[[package]]
name = "fp-storage"
version = "2.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"parity-scale-codec 3.1.5",
]
@@ -5445,7 +5445,7 @@
[[package]]
name = "pallet-base-fee"
version = "1.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"fp-evm",
"frame-support",
@@ -5660,7 +5660,7 @@
[[package]]
name = "pallet-ethereum"
version = "4.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"ethereum",
"ethereum-types",
@@ -5689,7 +5689,7 @@
[[package]]
name = "pallet-evm"
version = "6.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#64915c0986fcf2bbe942794b838c0cf359c93c21"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"
dependencies = [
"evm",
"fp-evm",
@@ -12130,7 +12130,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if 0.1.10",
"digest 0.10.3",
"rand 0.8.5",
"static_assertions",
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -126,8 +126,14 @@
fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {
let sponsor =
Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;
- let sponsor_sub = pallet_common::eth::convert_cross_account_to_uint256::<T>(&sponsor);
- Ok((*sponsor.as_eth(), sponsor_sub))
+ let result: (address, uint256) = if sponsor.is_canonical_substrate() {
+ let sponsor = pallet_common::eth::convert_cross_account_to_uint256::<T>(&sponsor);
+ (Default::default(), sponsor)
+ } else {
+ let sponsor = *sponsor.as_eth();
+ (sponsor, Default::default())
+ };
+ Ok(result)
}
/// Check tat contract has confirmed sponsor.
runtime/tests/src/lib.rsdiffbeforeafterboth--- a/runtime/tests/src/lib.rs
+++ b/runtime/tests/src/lib.rs
@@ -167,7 +167,7 @@
}
#[derive(Encode, Decode, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, TypeInfo, MaxEncodedLen)]
-pub struct TestCrossAccountId(u64, sp_core::H160);
+pub struct TestCrossAccountId(u64, sp_core::H160, bool);
impl CrossAccountId<u64> for TestCrossAccountId {
fn as_sub(&self) -> &u64 {
&self.0
@@ -178,17 +178,20 @@
fn from_sub(sub: u64) -> Self {
let mut eth = [0; 20];
eth[12..20].copy_from_slice(&sub.to_be_bytes());
- Self(sub, sp_core::H160(eth))
+ Self(sub, sp_core::H160(eth), true)
}
fn from_eth(eth: sp_core::H160) -> Self {
let mut sub_raw = [0; 8];
sub_raw.copy_from_slice(ð.0[0..8]);
let sub = u64::from_be_bytes(sub_raw);
- Self(sub, eth)
+ Self(sub, eth, false)
}
fn conv_eq(&self, other: &Self) -> bool {
self.as_sub() == other.as_sub()
}
+ fn is_canonical_substrate(&self) -> bool {
+ self.2
+ }
}
impl Default for TestCrossAccountId {
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('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('Sponsorship can not be confirmed by the address that not set as sponsor', async ({api, web3, privateKeyWrapper}) => {114 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);116 const flipper = await deployFlipper(web3, owner);117 const helpers = contractHelpers(web3, owner);118 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;119 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPendingSponsor');120 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;121 });122123 itWeb3('Get self sponsored sponsor', async ({api, web3, privateKeyWrapper}) => {124 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);125 const flipper = await deployFlipper(web3, owner);126 const helpers = contractHelpers(web3, owner);127 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();128 129 const result = await helpers.methods.getSponsor(flipper.options.address).call();130131 expect(result[0]).to.be.eq(flipper.options.address);132 const sponsorSub = api.registry.createType('AccountId', '0x' + BigInt(result[1]).toString(16).padStart(64, '0')).toJSON();133 expect(sponsorSub).to.be.eq(evmToAddress(flipper.options.address));134 });135136 itWeb3('Get confirmed sponsor', async ({api, web3, privateKeyWrapper}) => {137 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);138 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);139 const flipper = await deployFlipper(web3, owner);140 const helpers = contractHelpers(web3, owner);141 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();142 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});143 144 const result = await helpers.methods.getSponsor(flipper.options.address).call();145146 expect(result[0]).to.be.eq(sponsor);147 const sponsorSub = api.registry.createType('AccountId', '0x' + BigInt(result[1]).toString(16).padStart(64, '0')).toJSON();148 expect(sponsorSub).to.be.eq(evmToAddress(sponsor));149 });150151 itWeb3('Sponsor can be removed by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {152 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);153 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);154 const flipper = await deployFlipper(web3, owner);155 const helpers = contractHelpers(web3, owner);156157 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;158 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();159 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});160 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;161 162 await helpers.methods.removeSponsor(flipper.options.address).send();163 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;164 });165166 itWeb3('Sponsor can not be removed by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {167 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);168 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);169 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);170 const flipper = await deployFlipper(web3, owner);171 const helpers = contractHelpers(web3, owner);172173 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;174 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();175 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});176 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;177 178 await expect(helpers.methods.removeSponsor(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');179 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;180 });181182 itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {183 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);184 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);185 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);186187 const flipper = await deployFlipper(web3, owner);188189 const helpers = contractHelpers(web3, owner);190191 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();192 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});193194 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});195 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});196197 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);198 const callerBalanceBefore = await ethBalanceViaSub(api, caller);199200 await flipper.methods.flip().send({from: caller});201 expect(await flipper.methods.getValue().call()).to.be.true;202203 // Balance should be taken from sponsor instead of caller204 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);205 const callerBalanceAfter = await ethBalanceViaSub(api, caller);206 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;207 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);208 });209210 itWeb3('In generous mode, non-allowlisted user transaction will be self sponsored', async ({api, web3, privateKeyWrapper}) => {211 const alice = privateKeyWrapper('//Alice');212213 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);214 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);215216 const flipper = await deployFlipper(web3, owner);217218 const helpers = contractHelpers(web3, owner);219220 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();221222 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});223 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});224225 await transferBalanceToEth(api, alice, flipper.options.address);226227 const contractBalanceBefore = await ethBalanceViaSub(api, flipper.options.address);228 const callerBalanceBefore = await ethBalanceViaSub(api, caller);229230 await flipper.methods.flip().send({from: caller});231 expect(await flipper.methods.getValue().call()).to.be.true;232233 // Balance should be taken from sponsor instead of caller234 const contractBalanceAfter = await ethBalanceViaSub(api, flipper.options.address);235 const callerBalanceAfter = await ethBalanceViaSub(api, caller);236 expect(contractBalanceAfter < contractBalanceBefore).to.be.true;237 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);238 });239240 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}) => {241 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);242 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);243 const caller = createEthAccount(web3);244245 const flipper = await deployFlipper(web3, owner);246247 const helpers = contractHelpers(web3, owner);248 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});249 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});250251 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});252 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});253254 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();255 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});256257 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);258 expect(sponsorBalanceBefore).to.be.not.equal('0');259260 await flipper.methods.flip().send({from: caller});261 expect(await flipper.methods.getValue().call()).to.be.true;262263 // Balance should be taken from flipper instead of caller264 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);265 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;266 });267268 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}) => {269 const alice = privateKeyWrapper('//Alice');270271 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);272 const caller = createEthAccount(web3);273274 const flipper = await deployFlipper(web3, owner);275276 const helpers = contractHelpers(web3, owner);277278 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});279 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});280281 await transferBalanceToEth(api, alice, flipper.options.address);282283 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);284 expect(originalFlipperBalance).to.be.not.equal('0');285286 await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);287 expect(await flipper.methods.getValue().call()).to.be.false;288289 // Balance should be taken from flipper instead of caller290 const balanceAfter = await web3.eth.getBalance(flipper.options.address);291 expect(+balanceAfter).to.be.equals(+originalFlipperBalance);292 });293294 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}) => {295 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);296 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);297 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);298299 const flipper = await deployFlipper(web3, owner);300301 const helpers = contractHelpers(web3, owner);302 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});303 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});304305 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});306 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});307308 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();309 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});310311 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);312 const callerBalanceBefore = await ethBalanceViaSub(api, caller);313314 await flipper.methods.flip().send({from: caller});315 expect(await flipper.methods.getValue().call()).to.be.true;316317 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);318 const callerBalanceAfter = await ethBalanceViaSub(api, caller);319 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;320 expect(callerBalanceAfter).to.be.equals(callerBalanceBefore);321 });322323 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}) => {324 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);325 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);326 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);327 const originalCallerBalance = await web3.eth.getBalance(caller);328329 const flipper = await deployFlipper(web3, owner);330331 const helpers = contractHelpers(web3, owner);332 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});333 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});334335 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});336 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});337338 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();339 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});340341 const originalFlipperBalance = await web3.eth.getBalance(sponsor);342 expect(originalFlipperBalance).to.be.not.equal('0');343344 await flipper.methods.flip().send({from: caller});345 expect(await flipper.methods.getValue().call()).to.be.true;346 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);347348 const newFlipperBalance = await web3.eth.getBalance(sponsor);349 expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);350351 await flipper.methods.flip().send({from: caller});352 expect(await web3.eth.getBalance(sponsor)).to.be.equal(newFlipperBalance);353 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);354 });355356 // TODO: Find a way to calculate default rate limit357 itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {358 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);359 const flipper = await deployFlipper(web3, owner);360 const helpers = contractHelpers(web3, owner);361 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');362 });363});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('Sponsorship can not be confirmed by the address that not set as sponsor', async ({api, web3, privateKeyWrapper}) => {114 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);116 const flipper = await deployFlipper(web3, owner);117 const helpers = contractHelpers(web3, owner);118 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;119 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPendingSponsor');120 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;121 });122123 itWeb3('Get self sponsored sponsor', async ({api, web3, privateKeyWrapper}) => {124 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);125 const flipper = await deployFlipper(web3, owner);126 const helpers = contractHelpers(web3, owner);127 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();128 129 const result = await helpers.methods.getSponsor(flipper.options.address).call();130131 expect(result[0]).to.be.eq(flipper.options.address);132 expect(result[1]).to.be.eq('0');133 });134135 itWeb3('Get confirmed sponsor', async ({api, web3, privateKeyWrapper}) => {136 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);137 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);138 const flipper = await deployFlipper(web3, owner);139 const helpers = contractHelpers(web3, owner);140 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();141 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});142 143 const result = await helpers.methods.getSponsor(flipper.options.address).call();144145 expect(result[0]).to.be.eq(sponsor);146 expect(result[1]).to.be.eq('0');147 });148149 itWeb3('Sponsor can be removed by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {150 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);151 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);152 const flipper = await deployFlipper(web3, owner);153 const helpers = contractHelpers(web3, owner);154155 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;156 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();157 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});158 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;159 160 await helpers.methods.removeSponsor(flipper.options.address).send();161 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;162 });163164 itWeb3('Sponsor can not be removed by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {165 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);166 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);167 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);168 const flipper = await deployFlipper(web3, owner);169 const helpers = contractHelpers(web3, owner);170171 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;172 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();173 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});174 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;175 176 await expect(helpers.methods.removeSponsor(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');177 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;178 });179180 itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {181 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);182 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);183 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);184185 const flipper = await deployFlipper(web3, owner);186187 const helpers = contractHelpers(web3, owner);188189 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();190 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});191192 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});193 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});194195 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);196 const callerBalanceBefore = await ethBalanceViaSub(api, caller);197198 await flipper.methods.flip().send({from: caller});199 expect(await flipper.methods.getValue().call()).to.be.true;200201 // Balance should be taken from sponsor instead of caller202 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);203 const callerBalanceAfter = await ethBalanceViaSub(api, caller);204 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;205 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);206 });207208 itWeb3('In generous mode, non-allowlisted user transaction will be self sponsored', async ({api, web3, privateKeyWrapper}) => {209 const alice = privateKeyWrapper('//Alice');210211 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);212 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);213214 const flipper = await deployFlipper(web3, owner);215216 const helpers = contractHelpers(web3, owner);217218 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();219220 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});221 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});222223 await transferBalanceToEth(api, alice, flipper.options.address);224225 const contractBalanceBefore = await ethBalanceViaSub(api, flipper.options.address);226 const callerBalanceBefore = await ethBalanceViaSub(api, caller);227228 await flipper.methods.flip().send({from: caller});229 expect(await flipper.methods.getValue().call()).to.be.true;230231 // Balance should be taken from sponsor instead of caller232 const contractBalanceAfter = await ethBalanceViaSub(api, flipper.options.address);233 const callerBalanceAfter = await ethBalanceViaSub(api, caller);234 expect(contractBalanceAfter < contractBalanceBefore).to.be.true;235 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);236 });237238 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}) => {239 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);240 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);241 const caller = createEthAccount(web3);242243 const flipper = await deployFlipper(web3, owner);244245 const helpers = contractHelpers(web3, owner);246 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});247 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});248249 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});250 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});251252 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();253 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});254255 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);256 expect(sponsorBalanceBefore).to.be.not.equal('0');257258 await flipper.methods.flip().send({from: caller});259 expect(await flipper.methods.getValue().call()).to.be.true;260261 // Balance should be taken from flipper instead of caller262 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);263 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;264 });265266 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}) => {267 const alice = privateKeyWrapper('//Alice');268269 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);270 const caller = createEthAccount(web3);271272 const flipper = await deployFlipper(web3, owner);273274 const helpers = contractHelpers(web3, owner);275276 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});277 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});278279 await transferBalanceToEth(api, alice, flipper.options.address);280281 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);282 expect(originalFlipperBalance).to.be.not.equal('0');283284 await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);285 expect(await flipper.methods.getValue().call()).to.be.false;286287 // Balance should be taken from flipper instead of caller288 const balanceAfter = await web3.eth.getBalance(flipper.options.address);289 expect(+balanceAfter).to.be.equals(+originalFlipperBalance);290 });291292 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}) => {293 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);294 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);295 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);296297 const flipper = await deployFlipper(web3, owner);298299 const helpers = contractHelpers(web3, owner);300 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});301 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});302303 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});304 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});305306 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();307 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});308309 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);310 const callerBalanceBefore = await ethBalanceViaSub(api, caller);311312 await flipper.methods.flip().send({from: caller});313 expect(await flipper.methods.getValue().call()).to.be.true;314315 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);316 const callerBalanceAfter = await ethBalanceViaSub(api, caller);317 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;318 expect(callerBalanceAfter).to.be.equals(callerBalanceBefore);319 });320321 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}) => {322 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);323 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);324 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);325 const originalCallerBalance = await web3.eth.getBalance(caller);326327 const flipper = await deployFlipper(web3, owner);328329 const helpers = contractHelpers(web3, owner);330 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});331 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});332333 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});334 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});335336 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();337 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});338339 const originalFlipperBalance = await web3.eth.getBalance(sponsor);340 expect(originalFlipperBalance).to.be.not.equal('0');341342 await flipper.methods.flip().send({from: caller});343 expect(await flipper.methods.getValue().call()).to.be.true;344 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);345346 const newFlipperBalance = await web3.eth.getBalance(sponsor);347 expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);348349 await flipper.methods.flip().send({from: caller});350 expect(await web3.eth.getBalance(sponsor)).to.be.equal(newFlipperBalance);351 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);352 });353354 // TODO: Find a way to calculate default rate limit355 itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {356 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);357 const flipper = await deployFlipper(web3, owner);358 const helpers = contractHelpers(web3, owner);359 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');360 });361});