const { expect, assert } = require("chai"); const { ethers, network, config } = require("hardhat"); const { sendMinimalStakeAmount, resolveAddr, getOldRelayerRegistryContract, getManyEth, deployAndExecuteProposal, unregisterRelayer, tornAddr, governanceAddr, cheatingRelayers, getRelayerBalance, } = require("./utils"); describe("Proposal", function () { beforeEach(async function () { await network.provider.request({ method: "hardhat_reset", params: [ { forking: { jsonRpcUrl: config.networks.hardhat.forking.url, blockNumber: config.networks.hardhat.forking.blockNumber, }, }, ], }); }); describe("Unregister relayer", function () { it("Uregister relayer function should work", async function () { const testRelayerAddr = await resolveAddr("first-relayer.eth"); const relayerRegistryOldContract = await getOldRelayerRegistryContract(); let isRelayer = await relayerRegistryOldContract.isRelayer(testRelayerAddr); let isRelayerRegistered = await relayerRegistryOldContract.isRelayerRegistered(testRelayerAddr, testRelayerAddr); expect(isRelayer).to.equal(true); expect(isRelayerRegistered).to.equal(true); const { relayerRegistryContract } = await deployAndExecuteProposal(); await unregisterRelayer(testRelayerAddr); isRelayer = await relayerRegistryContract.isRelayer(testRelayerAddr); isRelayerRegistered = await relayerRegistryContract.isRelayerRegistered(testRelayerAddr, testRelayerAddr); expect(isRelayer).to.equal(false); expect(isRelayerRegistered).to.equal(false); }); it("Unregistered relayer should have zero balance", async function () { const testRelayerAddr = await resolveAddr("first-relayer.eth"); const { relayerRegistryContract } = await deployAndExecuteProposal(); await unregisterRelayer(testRelayerAddr); const relayerBalance = await relayerRegistryContract.getRelayerBalance(testRelayerAddr); expect(relayerBalance).to.equal(0); }); it("Unregister function should revert if called not by Governance", async function () { const { relayerRegistryContract } = await deployAndExecuteProposal(); const me = await resolveAddr("🦋️-effect.eth"); await getManyEth(me); const meAsSigner = await ethers.getImpersonatedSigner(me); const testRelayerAddr = await resolveAddr("first-relayer.eth"); const relayerRegistryWithMeAsSigner = relayerRegistryContract.connect(meAsSigner); await expect(relayerRegistryWithMeAsSigner.unregisterRelayer(testRelayerAddr)).to.be.revertedWith( "only governance", ); }); it("Tornado router address should be valid", async function () { const relayerRegistryOldContract = await getOldRelayerRegistryContract(); const oldRegistryRouterAddress = await relayerRegistryOldContract.tornadoRouter(); const { relayerRegistryContract } = await deployAndExecuteProposal(); expect(await relayerRegistryContract.tornadoRouter()).to.equal(oldRegistryRouterAddress); }); it("Aggregator contract data for unregistered relayers should be valid", async function () { const aggregatorAddr = "0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49"; const aggregatorContract = await ethers.getContractAt(require("./abi/aggregator.abi.json"), aggregatorAddr); const notRelayer = "🦋️-effect.eth"; const testRelayer = "first-relayer.eth"; const callAggr = async () => await aggregatorContract.relayersData([notRelayer, testRelayer].map(ethers.namehash), [ "mainnet-tornado", "bsc-tornado", ]); const oldData = await callAggr(); await deployAndExecuteProposal(); await unregisterRelayer(testRelayer); const newData = await callAggr(); assert.deepEqual(oldData[0], newData[0]); expect(oldData[1][1]).to.greaterThan(500n * 10n ** 18n); expect(newData[1][1]).to.equal(0); expect(oldData[1][2]).to.equal(true); expect(newData[1][2]).to.equal(false); }); it("Cheating relayers should be unregistered", async function () { const relayerRegistryOldContract = await getOldRelayerRegistryContract(); let areRegistered = await Promise.all(cheatingRelayers.map((r) => relayerRegistryOldContract.isRelayer(r))); let balances = await Promise.all(cheatingRelayers.map((r) => relayerRegistryOldContract.getRelayerBalance(r))); expect(areRegistered).satisfy((v) => v.every((v) => v === true)); expect(balances).satisfy((v) => v.every((v) => v >= 0n)); const { relayerRegistryContract } = await deployAndExecuteProposal(); areRegistered = await Promise.all(cheatingRelayers.map((r) => relayerRegistryContract.isRelayer(r))); balances = await Promise.all(cheatingRelayers.map((r) => relayerRegistryContract.getRelayerBalance(r))); expect(areRegistered).satisfy((v) => v.every((v) => v === false)); expect(balances).satisfy((v) => v.every((v) => v === 0n)); }); }); it("Unregistered relayers can register again", async function () { const { relayerRegistryContract } = await deployAndExecuteProposal(); const relayerEns = "moon-relayer.eth"; const unregisteredRelayer = await resolveAddr(relayerEns); const toStake = await sendMinimalStakeAmount(unregisteredRelayer); const relayerSigner = await ethers.getImpersonatedSigner(unregisteredRelayer); await relayerRegistryContract.connect(relayerSigner).register(relayerEns, toStake, []); const isRelayerRegistered = await relayerRegistryContract.isRelayerRegistered( unregisteredRelayer, unregisteredRelayer, ); const relayerBalance = await relayerRegistryContract.getRelayerBalance(unregisteredRelayer); expect(isRelayerRegistered).to.be.equal(true); expect(relayerBalance).to.be.equal(toStake); }); it("Gas expenses should be compensated to me", async function () { const tornContract = await ethers.getContractAt(require("./abi/torn.abi.json"), tornAddr); const me = await resolveAddr("butterfly-attractor.eth"); const initialTornBalance = await tornContract.balanceOf(me); await deployAndExecuteProposal(); expect((await tornContract.balanceOf(me)) - initialTornBalance).to.be.equal(30n * 10n ** 18n); }); it("Cheating relayers balances should be transferred from staking contract to governance", async function () { const tornContract = await ethers.getContractAt(require("./abi/torn.abi.json"), tornAddr); const stakingAddr = "0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29"; const initialStakingContractBalance = await tornContract.balanceOf(stakingAddr); const initialGovernanceBalance = await tornContract.balanceOf(governanceAddr); const cheatingRelayerBalanceSum = (await Promise.all(cheatingRelayers.map((r) => getRelayerBalance(r)))).reduce( (a, b) => a + b, ); const myCompensation = 30n * 10n ** 18n; await deployAndExecuteProposal(); expect(initialStakingContractBalance - (await tornContract.balanceOf(stakingAddr))).to.be.equal( cheatingRelayerBalanceSum, ); expect((await tornContract.balanceOf(governanceAddr)) - initialGovernanceBalance).to.be.equal( cheatingRelayerBalanceSum - myCompensation, ); }); });