--- a/tests/src/eth/contractSponsoring.test.ts +++ b/tests/src/eth/contractSponsoring.test.ts @@ -8,163 +8,224 @@ import { contractHelpers, createEthAccountWithBalance, - createEthAccount, transferBalanceToEth, deployFlipper, - usingWeb3Http, itWeb3 } from './util/helpers'; import waitNewBlocks from '../substrate/wait-new-blocks'; describe.only('Sponsoring EVM contracts', () => { - itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api}) => { - await usingWeb3Http(async web3Http => { - const owner = await createEthAccountWithBalance(api, web3Http); - const flipper = await deployFlipper(web3Http, owner); - await waitNewBlocks(api, 1); - const helpers = contractHelpers(web3Http, owner); - await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; - await waitNewBlocks(api, 1); - await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); - await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - }); + itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3}) => { + const owner = await createEthAccountWithBalance(api, web3); + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); + const helpers = contractHelpers(web3, owner); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + await waitNewBlocks(api, 1); + await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; }); - itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api}) => { - await usingWeb3Http(async web3Http => { - const owner = await createEthAccountWithBalance(api, web3Http); - const notOwner = await createEthAccountWithBalance(api, web3Http); - const flipper = await deployFlipper(web3Http, owner); - await waitNewBlocks(api, 1); - const helpers = contractHelpers(web3Http, owner); - await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; - await waitNewBlocks(api, 1); - await expect(helpers.methods.toggleSponsoring(notOwner, true).send({from: notOwner})).to.rejected; - await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; - }); + itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3}) => { + const owner = await createEthAccountWithBalance(api, web3); + const notOwner = await createEthAccountWithBalance(api, web3); + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); + const helpers = contractHelpers(web3, owner); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + await waitNewBlocks(api, 1); + await expect(helpers.methods.toggleSponsoring(notOwner, true).send({from: notOwner})).to.rejected; + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; }); - itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease', async ({api, web3}) => { - await usingWeb3Http(async web3Http => { - const alice = privateKey('//Alice'); + itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease (whitelisted)', async ({api, web3}) => { + const alice = privateKey('//Alice'); - const owner = await createEthAccountWithBalance(api, web3Http); - const caller = createEthAccount(web3Http); - const originalCallerBalance = await web3.eth.getBalance(caller); - expect(originalCallerBalance).to.be.equal('0'); + const owner = await createEthAccountWithBalance(api, web3); + const caller = await createEthAccountWithBalance(api, web3); - const flipper = await deployFlipper(web3Http, owner); - await waitNewBlocks(api, 1); + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); - const helpers = contractHelpers(web3Http, owner); - await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner }); - await waitNewBlocks(api, 1); - await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner }); - await waitNewBlocks(api, 1); + const helpers = contractHelpers(web3, owner); + await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner }); + await waitNewBlocks(api, 1); + await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner }); + await waitNewBlocks(api, 1); + + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); + await waitNewBlocks(api, 1); + await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; + + await transferBalanceToEth(api, alice, flipper.options.address); + await waitNewBlocks(api, 2); + + const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); + expect(originalFlipperBalance).to.be.not.equal('0'); + + await flipper.methods.flip().send({ from: caller }); + await waitNewBlocks(api, 1); + expect(await flipper.methods.getValue().call()).to.be.true; - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; - await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); - await waitNewBlocks(api, 1); - await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); - await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; + // Balance should be taken from flipper instead of caller + const balanceAfter = await web3.eth.getBalance(flipper.options.address); + expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance); + }); + + itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should not decrease (non-whitelisted)', async ({api, web3}) => { + const alice = privateKey('//Alice'); + + const owner = await createEthAccountWithBalance(api, web3); + const caller = await createEthAccountWithBalance(api, web3); + + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); + + const helpers = contractHelpers(web3, owner); + + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); + await waitNewBlocks(api, 1); + await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - await transferBalanceToEth(api, alice, flipper.options.address); - await waitNewBlocks(api, 2); + await transferBalanceToEth(api, alice, flipper.options.address); + await waitNewBlocks(api, 2); - const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); - expect(originalFlipperBalance).to.be.not.equal('0'); + const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); + expect(originalFlipperBalance).to.be.not.equal('0'); - await flipper.methods.flip().send({ from: caller }); - await waitNewBlocks(api, 1); - expect(await flipper.methods.getValue().call()).to.be.true; + await flipper.methods.flip().send({ from: caller }); + await waitNewBlocks(api, 1); + expect(await flipper.methods.getValue().call()).to.be.true; - // Balance should be taken from flipper instead of caller - const balanceAfter = await web3.eth.getBalance(flipper.options.address); - expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance); - }); + // Balance should be taken from flipper instead of caller + const balanceAfter = await web3.eth.getBalance(flipper.options.address); + expect(+balanceAfter).to.be.equals(+originalFlipperBalance); }); itWeb3('Sponsoring is set, an address that has UNQ can send a transaction and it works. User balance should not change', async ({api, web3}) => { - await usingWeb3Http(async web3Http => { - const alice = privateKey('//Alice'); + const alice = privateKey('//Alice'); - const owner = await createEthAccountWithBalance(api, web3Http); - const caller = createEthAccount(web3Http); - const originalCallerBalance = await web3.eth.getBalance(caller); - expect(originalCallerBalance).to.be.equal('0'); + const owner = await createEthAccountWithBalance(api, web3); + const caller = await createEthAccountWithBalance(api, web3); + const originalCallerBalance = await web3.eth.getBalance(caller); - const flipper = await deployFlipper(web3Http, owner); - await waitNewBlocks(api, 1); + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); - const helpers = contractHelpers(web3Http, owner); - await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner }); - await waitNewBlocks(api, 1); - await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner }); - await waitNewBlocks(api, 1); + const helpers = contractHelpers(web3, owner); + await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner }); + await waitNewBlocks(api, 1); + await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner }); + await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; - await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); - await waitNewBlocks(api, 1); - await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); - await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); + await waitNewBlocks(api, 1); + await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - await transferBalanceToEth(api, alice, flipper.options.address); - await waitNewBlocks(api, 2); + await transferBalanceToEth(api, alice, flipper.options.address); + await waitNewBlocks(api, 2); - const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); - expect(originalFlipperBalance).to.be.not.equal('0'); + const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); + expect(originalFlipperBalance).to.be.not.equal('0'); - await flipper.methods.flip().send({ from: caller }); - await waitNewBlocks(api, 1); - expect(await flipper.methods.getValue().call()).to.be.true; + await flipper.methods.flip().send({ from: caller }); + await waitNewBlocks(api, 1); + expect(await flipper.methods.getValue().call()).to.be.true; - expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance); - }); + expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance); }); itWeb3('Sponsoring is limited, with setContractRateLimit. The limitation is working if transactions are sent more often, the sender pays the commission.', async ({api, web3}) => { - await usingWeb3Http(async web3Http => { - const alice = privateKey('//Alice'); + const alice = privateKey('//Alice'); - const owner = await createEthAccountWithBalance(api, web3Http); - const caller = await createEthAccountWithBalance(api, web3Http); - const originalCallerBalance = await web3.eth.getBalance(caller); + const owner = await createEthAccountWithBalance(api, web3); + const caller = await createEthAccountWithBalance(api, web3); + const originalCallerBalance = await web3.eth.getBalance(caller); - const flipper = await deployFlipper(web3Http, owner); - await waitNewBlocks(api, 1); + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); - const helpers = contractHelpers(web3Http, owner); - await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner }); - await waitNewBlocks(api, 1); - await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner }); - await waitNewBlocks(api, 1); + const helpers = contractHelpers(web3, owner); + await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner }); + await waitNewBlocks(api, 1); + await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner }); + await waitNewBlocks(api, 1); + + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); + await waitNewBlocks(api, 1); + await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner}); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; + + await transferBalanceToEth(api, alice, flipper.options.address); + await waitNewBlocks(api, 2); + + const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); + expect(originalFlipperBalance).to.be.not.equal('0'); + + await flipper.methods.flip().send({ from: caller }); + await waitNewBlocks(api, 1); + expect(await flipper.methods.getValue().call()).to.be.true; + expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance); + + await flipper.methods.flip().send({ from: caller }); + await waitNewBlocks(api, 1); + expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance); + }); + + itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3}) => { + const owner = await createEthAccountWithBalance(api, web3); + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); + const helpers = contractHelpers(web3, owner); + await waitNewBlocks(api, 1); + expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200'); + }); + + itWeb3('If whitelist mode is off and sponsorship is on, sponsorship does not work', async ({api, web3}) => { + const alice = privateKey('//Alice'); + + const owner = await createEthAccountWithBalance(api, web3); + const caller = await createEthAccountWithBalance(api, web3); + + const flipper = await deployFlipper(web3, owner); + await waitNewBlocks(api, 1); + + const helpers = contractHelpers(web3, owner); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; - await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); - await waitNewBlocks(api, 1); - await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner}); - await waitNewBlocks(api, 1); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner}); + await waitNewBlocks(api, 1); + await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); + await waitNewBlocks(api, 1); + expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - await transferBalanceToEth(api, alice, flipper.options.address); - await waitNewBlocks(api, 2); + await transferBalanceToEth(api, alice, flipper.options.address); + await waitNewBlocks(api, 2); - const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); - expect(originalFlipperBalance).to.be.not.equal('0'); + const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); + expect(originalFlipperBalance).to.be.not.equal('0'); - await flipper.methods.flip().send({ from: caller }); - await waitNewBlocks(api, 1); - expect(await flipper.methods.getValue().call()).to.be.true; - expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance); + await flipper.methods.flip().send({ from: caller }); + await waitNewBlocks(api, 1); + expect(await flipper.methods.getValue().call()).to.be.true; - await flipper.methods.flip().send({ from: caller }); - await waitNewBlocks(api, 1); - expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance); - }); + // Balance should be taken from flipper instead of caller + const balanceAfter = await web3.eth.getBalance(flipper.options.address); + expect(+balanceAfter).to.be.equals(+originalFlipperBalance); }); + }); --- a/tests/src/eth/util/contractHelpersAbi.json +++ b/tests/src/eth/util/contractHelpersAbi.json @@ -3,11 +3,16 @@ "inputs": [ { "internalType": "address", - "name": "contract", + "name": "contractAddress", "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" } ], - "name": "allowlistEnabled", + "name": "allowed", "outputs": [ { "internalType": "bool", @@ -22,16 +27,11 @@ "inputs": [ { "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "address", - "name": "caller", + "name": "contractAddress", "type": "address" } ], - "name": "allowed", + "name": "allowlistEnabled", "outputs": [ { "internalType": "bool", @@ -46,7 +46,7 @@ "inputs": [ { "internalType": "address", - "name": "target", + "name": "contractAddress", "type": "address" } ], @@ -65,16 +65,16 @@ "inputs": [ { "internalType": "address", - "name": "target", + "name": "contractAddress", "type": "address" } ], - "name": "sponsoringEnabled", + "name": "getSponsoringRateLimit", "outputs": [ { - "internalType": "bool", + "internalType": "uint32", "name": "", - "type": "bool" + "type": "uint32" } ], "stateMutability": "view", @@ -84,39 +84,58 @@ "inputs": [ { "internalType": "address", - "name": "target", + "name": "contractAddress", "type": "address" }, { + "internalType": "uint32", + "name": "rateLimit", + "type": "uint32" + } + ], + "name": "setSponsoringRateLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", - "name": "user", + "name": "contractAddress", "type": "address" - }, + } + ], + "name": "sponsoringEnabled", + "outputs": [ { "internalType": "bool", - "name": "isAllowed", + "name": "", "type": "bool" } ], - "name": "toggleAllowed", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "target", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "user", "type": "address" }, { "internalType": "bool", - "name": "enabled", + "name": "allowed", "type": "bool" } ], - "name": "toggleAllowlist", + "name": "toggleAllowed", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -125,7 +144,7 @@ "inputs": [ { "internalType": "address", - "name": "target", + "name": "contractAddress", "type": "address" }, { @@ -134,7 +153,7 @@ "type": "bool" } ], - "name": "toggleSponsoring", + "name": "toggleAllowlist", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -143,16 +162,16 @@ "inputs": [ { "internalType": "address", - "name": "target", + "name": "contractAddress", "type": "address" }, { - "internalType": "uint32", - "name": "limit", - "type": "uint32" + "internalType": "bool", + "name": "enabled", + "type": "bool" } ], - "name": "setSponsoringRateLimit", + "name": "toggleSponsoring", "outputs": [], "stateMutability": "nonpayable", "type": "function"