difftreelog
Merge pull request #281 from UniqueNetwork/feature/contract-sponsoring-modes
in: master
Generous contract sponsoring mode
12 files changed
crates/evm-coder/src/abi.rsdiffbeforeafterboth95 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))95 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))96 }96 }9798 pub fn uint8(&mut self) -> Result<u8> {99 Ok(self.read_padleft::<1>()?[0])100 }9710198 pub fn uint32(&mut self) -> Result<u32> {102 pub fn uint32(&mut self) -> Result<u32> {99 Ok(u32::from_be_bytes(self.read_padleft()?))103 Ok(u32::from_be_bytes(self.read_padleft()?))243 };247 };244}248}245249250impl_abi_readable!(u8, uint8);246impl_abi_readable!(u32, uint32);251impl_abi_readable!(u32, uint32);247impl_abi_readable!(u64, uint64);252impl_abi_readable!(u64, uint64);248impl_abi_readable!(u128, uint128);253impl_abi_readable!(u128, uint128);pallets/evm-contract-helpers/exp.rsdiffbeforeafterbothno changes
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth4use pallet_evm::{ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure};4use pallet_evm::{ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure};5use sp_core::H160;5use sp_core::H160;6use crate::{6use crate::{7 AllowlistEnabled, Config, Owner, Pallet, SelfSponsoring, SponsorBasket, SponsoringRateLimit,7 AllowlistEnabled, Config, Owner, Pallet, SponsorBasket, SponsoringRateLimit, SponsoringModeT,8};8};9use frame_support::traits::Get;9use frame_support::traits::Get;10use up_sponsorship::SponsorshipHandler;10use up_sponsorship::SponsorshipHandler;28 }28 }292930 fn sponsoring_enabled(&self, contract_address: address) -> Result<bool> {30 fn sponsoring_enabled(&self, contract_address: address) -> Result<bool> {31 Ok(<SelfSponsoring<T>>::get(contract_address))31 Ok(<Pallet<T>>::sponsoring_mode(contract_address) != SponsoringModeT::Disabled)32 }32 }333334 /// Deprecated34 fn toggle_sponsoring(35 fn toggle_sponsoring(35 &mut self,36 &mut self,36 caller: caller,37 caller: caller,42 Ok(())43 Ok(())43 }44 }4546 fn set_sponsoring_mode(47 &mut self,48 caller: caller,49 contract_address: address,50 mode: uint8,51 ) -> Result<void> {52 <Pallet<T>>::ensure_owner(contract_address, caller)?;53 let mode = SponsoringModeT::from_eth(mode).ok_or("unknown mode")?;54 <Pallet<T>>::set_sponsoring_mode(contract_address, mode);55 Ok(())56 }5758 fn sponsoring_mode(&self, contract_address: address) -> Result<uint8> {59 Ok(<Pallet<T>>::sponsoring_mode(contract_address).to_eth())60 }446145 fn set_sponsoring_rate_limit(62 fn set_sponsoring_rate_limit(46 &mut self,63 &mut self,146pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);163pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);147impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for HelpersContractSponsoring<T> {164impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for HelpersContractSponsoring<T> {148 fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {165 fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {149 if !<SelfSponsoring<T>>::get(&call.0) {166 let mode = <Pallet<T>>::sponsoring_mode(call.0);150 return None;167 if mode == SponsoringModeT::Disabled {151 }168 return None;169 }152 if !<Pallet<T>>::allowed(call.0, *who) {170 if mode == SponsoringModeT::Allowlisted && !<Pallet<T>>::allowed(call.0, *who) {153 return None;171 return None;154 }172 }155 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;173 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;pallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth1#![cfg_attr(not(feature = "std"), no_std)]1#![cfg_attr(not(feature = "std"), no_std)]223use codec::{Decode, Encode, MaxEncodedLen};3pub use pallet::*;4pub use pallet::*;4pub use eth::*;5pub use eth::*;6use scale_info::TypeInfo;5pub mod eth;7pub mod eth;687#[frame_support::pallet]9#[frame_support::pallet]8pub mod pallet {10pub mod pallet {11 pub use super::*;9 use evm_coder::execution::Result;12 use evm_coder::execution::Result;10 use frame_support::pallet_prelude::*;13 use frame_support::pallet_prelude::*;11 use sp_core::H160;14 use sp_core::H160;31 StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;34 StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;323533 #[pallet::storage]36 #[pallet::storage]37 #[deprecated]34 pub(super) type SelfSponsoring<T: Config> =38 pub(super) type SelfSponsoring<T: Config> =35 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;39 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;4041 #[pallet::storage]42 pub(super) type SponsoringMode<T: Config> =43 StorageMap<Hasher = Twox128, Key = H160, Value = SponsoringModeT, QueryKind = OptionQuery>;364437 #[pallet::storage]45 #[pallet::storage]38 pub(super) type SponsoringRateLimit<T: Config> = StorageMap<46 pub(super) type SponsoringRateLimit<T: Config> = StorageMap<68 >;76 >;697770 impl<T: Config> Pallet<T> {78 impl<T: Config> Pallet<T> {79 pub fn sponsoring_mode(contract: H160) -> SponsoringModeT {80 <SponsoringMode<T>>::get(contract)81 .or_else(|| {82 <SelfSponsoring<T>>::get(contract).then(|| SponsoringModeT::Allowlisted)83 })84 .unwrap_or_default()85 }86 pub fn set_sponsoring_mode(contract: H160, mode: SponsoringModeT) {87 if mode == SponsoringModeT::Disabled {88 <SponsoringMode<T>>::remove(contract);89 } else {90 <SponsoringMode<T>>::insert(contract, mode);91 }92 <SelfSponsoring<T>>::remove(contract)93 }9471 pub fn toggle_sponsoring(contract: H160, enabled: bool) {95 pub fn toggle_sponsoring(contract: H160, enabled: bool) {72 <SelfSponsoring<T>>::insert(contract, enabled);96 Self::set_sponsoring_mode(97 contract,98 if enabled {99 SponsoringModeT::Allowlisted100 } else {101 SponsoringModeT::Disabled102 },103 )73 }104 }7410595 }126 }96}127}128129#[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen)]130pub enum SponsoringModeT {131 Disabled,132 Allowlisted,133 Generous,134}135136impl SponsoringModeT {137 fn from_eth(v: u8) -> Option<Self> {138 Some(match v {139 0 => Self::Disabled,140 1 => Self::Allowlisted,141 2 => Self::Generous,142 _ => return None,143 })144 }145 fn to_eth(self) -> u8 {146 match self {147 SponsoringModeT::Disabled => 0,148 SponsoringModeT::Allowlisted => 1,149 SponsoringModeT::Generous => 2,150 }151 }152}153154impl Default for SponsoringModeT {155 fn default() -> Self {156 Self::Disabled157 }158}97159pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth21 }21 }22}22}232324// Selector: 31acb1fe24// Selector: 7b4866f925contract ContractHelpers is Dummy, ERC165 {25contract ContractHelpers is Dummy, ERC165 {26 // Selector: contractOwner(address) 5152b14c26 // Selector: contractOwner(address) 5152b14c27 function contractOwner(address contractAddress)27 function contractOwner(address contractAddress)47 return false;47 return false;48 }48 }494950 // Deprecated51 //50 // Selector: toggleSponsoring(address,bool) fcac6d8652 // Selector: toggleSponsoring(address,bool) fcac6d8651 function toggleSponsoring(address contractAddress, bool enabled) public {53 function toggleSponsoring(address contractAddress, bool enabled) public {52 require(false, stub_error);54 require(false, stub_error);55 dummy = 0;57 dummy = 0;56 }58 }5960 // Selector: setSponsoringMode(address,uint8) fde8a56061 function setSponsoringMode(address contractAddress, uint8 mode) public {62 require(false, stub_error);63 contractAddress;64 mode;65 dummy = 0;66 }6768 // Selector: sponsoringMode(address) b70c726769 function sponsoringMode(address contractAddress)70 public71 view72 returns (uint8)73 {74 require(false, stub_error);75 contractAddress;76 dummy;77 return 0;78 }577958 // Selector: setSponsoringRateLimit(address,uint32) 77b6c90880 // Selector: setSponsoringRateLimit(address,uint32) 77b6c90859 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)81 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)tests/src/eth/api/ContractHelpers.soldiffbeforeafterboth12 function supportsInterface(bytes4 interfaceID) external view returns (bool);12 function supportsInterface(bytes4 interfaceID) external view returns (bool);13}13}141415// Selector: 31acb1fe15// Selector: 7b4866f916interface ContractHelpers is Dummy, ERC165 {16interface ContractHelpers is Dummy, ERC165 {17 // Selector: contractOwner(address) 5152b14c17 // Selector: contractOwner(address) 5152b14c18 function contractOwner(address contractAddress)18 function contractOwner(address contractAddress)26 view26 view27 returns (bool);27 returns (bool);282829 // Deprecated30 //29 // Selector: toggleSponsoring(address,bool) fcac6d8631 // Selector: toggleSponsoring(address,bool) fcac6d8630 function toggleSponsoring(address contractAddress, bool enabled) external;32 function toggleSponsoring(address contractAddress, bool enabled) external;3334 // Selector: setSponsoringMode(address,uint8) fde8a56035 function setSponsoringMode(address contractAddress, uint8 mode) external;3637 // Selector: sponsoringMode(address) b70c726738 function sponsoringMode(address contractAddress)39 external40 view41 returns (uint8);314232 // Selector: setSponsoringRateLimit(address,uint32) 77b6c90843 // Selector: setSponsoringRateLimit(address,uint32) 77b6c90833 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)44 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)tests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth10 createEthAccountWithBalance,10 createEthAccountWithBalance,11 transferBalanceToEth,11 transferBalanceToEth,12 deployFlipper,12 deployFlipper,13 itWeb3} from './util/helpers';13 itWeb3,14 SponsoringMode,15 createEthAccount,16} from './util/helpers';141715describe('Sponsoring EVM contracts', () => {18describe('Sponsoring EVM contracts', () => {18 const flipper = await deployFlipper(web3, owner);21 const flipper = await deployFlipper(web3, owner);19 const helpers = contractHelpers(web3, owner);22 const helpers = contractHelpers(web3, owner);20 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;23 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;21 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});24 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});22 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;25 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;23 });26 });242728 const flipper = await deployFlipper(web3, owner);31 const flipper = await deployFlipper(web3, owner);29 const helpers = contractHelpers(web3, owner);32 const helpers = contractHelpers(web3, owner);30 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;33 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;31 await expect(helpers.methods.toggleSponsoring(notOwner, true).send({from: notOwner})).to.rejected;34 await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).send({from: notOwner})).to.rejected;32 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;35 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;33 });36 });3738 itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3}) => {39 const alice = privateKey('//Alice');4041 const owner = await createEthAccountWithBalance(api, web3);42 const caller = await createEthAccountWithBalance(api, web3);4344 const flipper = await deployFlipper(web3, owner);4546 const helpers = contractHelpers(web3, owner);4748 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;49 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});50 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});51 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;5253 await transferBalanceToEth(api, alice, flipper.options.address);5455 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);56 expect(originalFlipperBalance).to.be.not.equal('0');5758 await flipper.methods.flip().send({from: caller});59 expect(await flipper.methods.getValue().call()).to.be.true;6061 // Balance should be taken from flipper instead of caller62 const balanceAfter = await web3.eth.getBalance(flipper.options.address);63 expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance);64 });346535 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}) => {66 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}) => {36 const alice = privateKey('//Alice');67 const alice = privateKey('//Alice');376838 const owner = await createEthAccountWithBalance(api, web3);69 const owner = await createEthAccountWithBalance(api, web3);39 const caller = await createEthAccountWithBalance(api, web3);70 const caller = createEthAccount(web3);407141 const flipper = await deployFlipper(web3, owner);72 const flipper = await deployFlipper(web3, owner);427345 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});76 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});467747 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;78 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;48 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});79 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});49 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});80 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});50 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;81 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;518266 const alice = privateKey('//Alice');97 const alice = privateKey('//Alice');679868 const owner = await createEthAccountWithBalance(api, web3);99 const owner = await createEthAccountWithBalance(api, web3);69 const caller = await createEthAccountWithBalance(api, web3);100 const caller = createEthAccount(web3);7010171 const flipper = await deployFlipper(web3, owner);102 const flipper = await deployFlipper(web3, owner);7210373 const helpers = contractHelpers(web3, owner);104 const helpers = contractHelpers(web3, owner);7410575 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;106 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;76 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});107 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});77 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});108 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});78 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;109 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;79110104 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});135 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});105136106 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;137 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;107 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});138 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});108 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});139 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});109 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;140 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;110141133 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});164 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});134165135 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;166 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;136 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});167 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});137 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});168 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});138 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;169 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;139170158 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');189 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');159 });190 });160161 itWeb3('If allowlist mode is off and sponsorship is on, sponsorship does not work', async ({api, web3}) => {162 const alice = privateKey('//Alice');163164 const owner = await createEthAccountWithBalance(api, web3);165 const caller = await createEthAccountWithBalance(api, web3);166167 const flipper = await deployFlipper(web3, owner);168169 const helpers = contractHelpers(web3, owner);170171 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;172 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});173 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});174 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;175176 await transferBalanceToEth(api, alice, flipper.options.address);177178 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);179 expect(originalFlipperBalance).to.be.not.equal('0');180181 await flipper.methods.flip().send({from: caller});182 expect(await flipper.methods.getValue().call()).to.be.true;183184 // Balance should be taken from flipper instead of caller185 const balanceAfter = await web3.eth.getBalance(flipper.options.address);186 expect(+balanceAfter).to.be.equals(+originalFlipperBalance);187 });188189});191});190192tests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth2import {getBalanceSingle, transferBalanceExpectSuccess} from '../../substrate/get-balance';2import {getBalanceSingle, transferBalanceExpectSuccess} from '../../substrate/get-balance';3import privateKey from '../../substrate/privateKey';3import privateKey from '../../substrate/privateKey';4import {addToAllowListExpectSuccess, confirmSponsorshipExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, getTokenOwner, setCollectionLimitsExpectSuccess, setCollectionSponsorExpectSuccess, transferExpectSuccess, transferFromExpectSuccess} from '../../util/helpers';4import {addToAllowListExpectSuccess, confirmSponsorshipExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, getTokenOwner, setCollectionLimitsExpectSuccess, setCollectionSponsorExpectSuccess, transferExpectSuccess, transferFromExpectSuccess} from '../../util/helpers';5import {collectionIdToAddress, contractHelpers, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, subToEth, subToEthLowercase, transferBalanceToEth} from '../util/helpers';5import {collectionIdToAddress, contractHelpers, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, SponsoringMode, subToEth, subToEthLowercase, transferBalanceToEth} from '../util/helpers';6import {evmToAddress} from '@polkadot/util-crypto';6import {evmToAddress} from '@polkadot/util-crypto';7import nonFungibleAbi from '../nonFungibleAbi.json';7import nonFungibleAbi from '../nonFungibleAbi.json';8import fungibleAbi from '../fungibleAbi.json';8import fungibleAbi from '../fungibleAbi.json';20 });20 });21 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});21 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});22 const helpers = contractHelpers(web3, matcherOwner);22 const helpers = contractHelpers(web3, matcherOwner);23 await helpers.methods.toggleSponsoring(matcher.options.address, true).send({from: matcherOwner});23 await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});24 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});24 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});25 await transferBalanceToEth(api, alice, matcher.options.address);25 await transferBalanceToEth(api, alice, matcher.options.address);2626147 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner, gas: 10000000});147 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner, gas: 10000000});148 await matcher.methods.setEscrow(escrow).send({from: matcherOwner});148 await matcher.methods.setEscrow(escrow).send({from: matcherOwner});149 const helpers = contractHelpers(web3, matcherOwner);149 const helpers = contractHelpers(web3, matcherOwner);150 await helpers.methods.toggleSponsoring(matcher.options.address, true).send({from: matcherOwner});150 await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});151 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});151 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});152 await transferBalanceToEth(api, alice, matcher.options.address);152 await transferBalanceToEth(api, alice, matcher.options.address);153153tests/src/eth/sponsoring.test.tsdiffbeforeafterboth1import {expect} from 'chai';1import {expect} from 'chai';2import privateKey from '../substrate/privateKey';2import privateKey from '../substrate/privateKey';3import {contractHelpers, createEthAccount, createEthAccountWithBalance, deployCollector, deployFlipper, itWeb3, transferBalanceToEth} from './util/helpers';3import {contractHelpers, createEthAccount, createEthAccountWithBalance, deployCollector, deployFlipper, itWeb3, SponsoringMode, transferBalanceToEth} from './util/helpers';445describe('EVM sponsoring', () => {5describe('EVM sponsoring', () => {6 itWeb3('Fee is deducted from contract if sponsoring is enabled', async ({api, web3}) => {6 itWeb3('Fee is deducted from contract if sponsoring is enabled', async ({api, web3}) => {18 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});18 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});191920 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;20 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;21 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});21 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});22 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});22 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});23 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;23 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;242449 await helpers.methods.toggleAllowed(collector.options.address, caller, true).send({from: owner});49 await helpers.methods.toggleAllowed(collector.options.address, caller, true).send({from: owner});505051 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.false;51 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.false;52 await helpers.methods.toggleSponsoring(collector.options.address, true).send({from: owner});52 await helpers.methods.setSponsoringMode(collector.options.address, SponsoringMode.Allowlisted).send({from: owner});53 await helpers.methods.setSponsoringRateLimit(collector.options.address, 0).send({from: owner});53 await helpers.methods.setSponsoringRateLimit(collector.options.address, 0).send({from: owner});54 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.true;54 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.true;5555tests/src/eth/util/contractHelpersAbi.jsondiffbeforeafterboth139 "stateMutability": "nonpayable",139 "stateMutability": "nonpayable",140 "type": "function"140 "type": "function"141 },141 },142 {143 "inputs": [144 {145 "internalType": "address",146 "name": "target",147 "type": "address"148 },149 {150 "internalType": "uint8",151 "name": "mode",152 "type": "uint8"153 }154 ],155 "name": "setSponsoringMode",156 "outputs": [],157 "stateMutability": "nonpayable",158 "type": "function"159 },160 {161 "inputs": [162 {163 "internalType": "address",164 "name": "target",165 "type": "address"166 }167 ],168 "name": "sponsoringMode",169 "outputs": [170 {171 "internalType": "uint8",172 "name": "",173 "type": "uint8"174 }175 ],176 "stateMutability": "nonpayable",177 "type": "function"178 },142 {179 {143 "inputs": [180 "inputs": [144 {181 {tests/src/eth/util/helpers.tsdiffbeforeafterboth212122export const GAS_ARGS = {gas: 2500000};22export const GAS_ARGS = {gas: 2500000};2324export enum SponsoringMode {25 Disabled = 0,26 Allowlisted = 1,27 Generous = 2,28}232924let web3Connected = false;30let web3Connected = false;25export async function usingWeb3<T>(cb: (web3: Web3) => Promise<T> | T): Promise<T> {31export async function usingWeb3<T>(cb: (web3: Web3) => Promise<T> | T): Promise<T> {