From e7a0cc1e06b85dd1b65365cdf4021dfe44ad1195 Mon Sep 17 00:00:00 2001 From: Jonathan Oppenheimer Date: Wed, 3 Dec 2025 13:15:43 -0500 Subject: [PATCH 1/6] feat: convert tx allow list npm test to go test --- contracts/contracts/ExampleTxAllowList.sol | 20 -- contracts/scripts/deployExampleTxAllowList.ts | 16 - contracts/tasks.ts | 36 --- contracts/test/tx_allow_list.ts | 135 -------- .../allowlisttest/test_allowlist_events.go | 150 +++++++++ .../deployerallowlist/simulated_test.go | 129 +------- .../contracts/txallowlist/simulated_test.go | 296 ++++++++++++++++++ tests/precompile/genesis/tx_allow_list.json | 48 --- tests/precompile/solidity/suites.go | 8 - 9 files changed, 448 insertions(+), 390 deletions(-) delete mode 100644 contracts/contracts/ExampleTxAllowList.sol delete mode 100644 contracts/scripts/deployExampleTxAllowList.ts delete mode 100644 contracts/test/tx_allow_list.ts create mode 100644 precompile/allowlist/allowlisttest/test_allowlist_events.go create mode 100644 precompile/contracts/txallowlist/simulated_test.go delete mode 100644 tests/precompile/genesis/tx_allow_list.json diff --git a/contracts/contracts/ExampleTxAllowList.sol b/contracts/contracts/ExampleTxAllowList.sol deleted file mode 100644 index 0bc9e23da6..0000000000 --- a/contracts/contracts/ExampleTxAllowList.sol +++ /dev/null @@ -1,20 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "./AllowList.sol"; -import "./interfaces/IAllowList.sol"; - -// Precompiled Allow List Contract Address -address constant TX_ALLOW_LIST = 0x0200000000000000000000000000000000000002; - -// ExampleTxAllowList shows how TxAllowList precompile can be used in a smart contract -// All methods of [allowList] can be directly called. There are example calls as tasks in hardhat.config.ts file. -contract ExampleTxAllowList is AllowList { - constructor() AllowList(TX_ALLOW_LIST) {} - - function deployContract() public { - new Example(); - } -} - -contract Example {} diff --git a/contracts/scripts/deployExampleTxAllowList.ts b/contracts/scripts/deployExampleTxAllowList.ts deleted file mode 100644 index 8350a06941..0000000000 --- a/contracts/scripts/deployExampleTxAllowList.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ethers } from "hardhat" -import { ExampleTxAllowList } from "typechain-types" - -const main = async (): Promise => { - const contract: ExampleTxAllowList = await ethers.deployContract("ExampleTxAllowList") - - await contract.waitForDeployment() - console.log(`Contract deployed to: ${contract.target}`) -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error) - process.exit(1) - }) diff --git a/contracts/tasks.ts b/contracts/tasks.ts index 7964e8bed1..1db1879e68 100644 --- a/contracts/tasks.ts +++ b/contracts/tasks.ts @@ -81,42 +81,6 @@ task("deployerAllowList:revoke", "Removes the address from the list") await getRole(allowList, args.address) }) -// npx hardhat allowList:readRole --network local --address [address] -task("txAllowList:readRole", "Gets the network transaction allow list") - .addParam("address", "the address you want to know the allowlist role for") - .setAction(async (args, hre) => { - const allowList = await hre.ethers.getContractAt("IAllowList", TX_ALLOW_LIST_ADDRESS) - await getRole(allowList, args.address) - }) - -// npx hardhat allowList:addDeployer --network local --address [address] -task("txAllowList:addDeployer", "Adds an address to the transaction allow list") - .addParam("address", "the address you want to add as a deployer") - .setAction(async (args, hre) => { - const allowList = await hre.ethers.getContractAt("IAllowList", TX_ALLOW_LIST_ADDRESS) - // ADD CODE BELOW - await allowList.setEnabled(args.address) - await getRole(allowList, args.address) - }) - -// npx hardhat allowList:addAdmin --network local --address [address] -task("txAllowList:addAdmin", "Adds an admin on the transaction allow list") - .addParam("address", "the address you want to add as a admin") - .setAction(async (args, hre) => { - const allowList = await hre.ethers.getContractAt("IAllowList", TX_ALLOW_LIST_ADDRESS) - await allowList.setAdmin(args.address) - await getRole(allowList, args.address) - }) - -// npx hardhat allowList:revoke --network local --address [address] -task("txAllowList:revoke", "Removes the address from the transaction allow list") - .addParam("address", "the address you want to revoke all permission") - .setAction(async (args, hre) => { - const allowList = await hre.ethers.getContractAt("IAllowList", TX_ALLOW_LIST_ADDRESS) - await allowList.setNone(args.address) - await getRole(allowList, args.address) - }) - // npx hardhat minter:readRole --network local --address [address] task("minter:readRole", "Gets the network deployer minter list") .addParam("address", "the address you want to know the minter role for") diff --git a/contracts/test/tx_allow_list.ts b/contracts/test/tx_allow_list.ts deleted file mode 100644 index bd9e7830e4..0000000000 --- a/contracts/test/tx_allow_list.ts +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -import { ethers } from "hardhat" -import { Roles, test } from "./utils" -import { expect } from "chai"; -import { Contract, Signer } from "ethers" -import { IAllowList } from "typechain-types"; - -// make sure this is always an admin for minter precompile -const ADMIN_ADDRESS = "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC" -const OTHER_SIGNER = "0x0Fa8EA536Be85F32724D57A37758761B86416123" -const TX_ALLOW_LIST_ADDRESS = "0x0200000000000000000000000000000000000002" - -describe("ExampleTxAllowList", function () { - beforeEach('Setup DS-Test contract', async function () { - const signer = await ethers.getSigner(ADMIN_ADDRESS) - const allowListPromise = ethers.getContractAt("IAllowList", TX_ALLOW_LIST_ADDRESS, signer) - - return ethers.getContractFactory("ExampleTxAllowListTest", { signer }) - .then(factory => factory.deploy()) - .then(contract => { - this.testContract = contract - return Promise.all([ - contract.waitForDeployment().then(() => contract), - allowListPromise.then(allowList => allowList.setAdmin(contract.target)).then(tx => tx.wait()), - ]) - }) - .then(([contract]) => contract.setUp()) - .then(tx => tx.wait()) - }) - - test("should add contract deployer as admin", "step_contractOwnerIsAdmin") - - test("precompile should see admin address has admin role", "step_precompileHasDeployerAsAdmin") - - test("precompile should see test address has no role", "step_newAddressHasNoRole") - - test("contract should report test address has on admin role", "step_noRoleIsNotAdmin") - - test("contract should report admin address has admin role", "step_exampleAllowListReturnsTestIsAdmin") - - test("should not let test address submit txs", [ - { - method: "step_fromOther", - overrides: { from: OTHER_SIGNER }, - shouldFail: true, - }, - { - method: "step_enableOther", - overrides: { from: ADMIN_ADDRESS }, - shouldFail: false, - }, - { - method: "step_fromOther", - overrides: { from: OTHER_SIGNER }, - shouldFail: false, - }, - ]); - - test("should not allow noRole to enable itself", "step_noRoleCannotEnableItself") - - test("should allow admin to add contract as admin", "step_addContractAsAdmin") - - test("should allow admin to add allowed address as allowed through contract", "step_enableThroughContract") - - test("should let allowed address deploy", "step_canDeploy") - - test("should not let allowed add another allowed", "step_onlyAdminCanEnable") - - test("should not let allowed to revoke admin", "step_onlyAdminCanRevoke") - - test("should let admin to revoke allowed", "step_adminCanRevoke") - - test("should let manager to add allowed", "step_managerCanAllow") - - test("should let manager to revoke allowed", "step_managerCanRevoke") - - test("should not let manager to revoke admin", "step_managerCannotRevokeAdmin") - - test("should not let manager to add admin", "step_managerCannotGrantAdmin") - - test("should not let manager to add manager", "step_managerCannotGrantManager") - - test("should not let manager to revoke manager", "step_managerCannotRevokeManager") - - test("should let manager to deploy", "step_managerCanDeploy") -}) - -describe("IAllowList", function () { - let owner: Signer - let ownerAddress: string - let contract: IAllowList - before(async function () { - owner = await ethers.getSigner(ADMIN_ADDRESS); - ownerAddress = await owner.getAddress() - contract = await ethers.getContractAt("IAllowList", TX_ALLOW_LIST_ADDRESS, owner) - }); - - it("should emit event after set admin", async function () { - let testAddress = "0x0111000000000000000000000000000000000001" - let tx = await contract.setAdmin(testAddress) - let receipt = await tx.wait() - await expect(receipt) - .to.emit(contract, 'RoleSet') - .withArgs(Roles.Admin, testAddress, ownerAddress, Roles.None) - }) - - it("should emit event after set manager", async function () { - let testAddress = "0x0222000000000000000000000000000000000002" - let tx = await contract.setManager(testAddress) - let receipt = await tx.wait() - await expect(receipt) - .to.emit(contract, 'RoleSet') - .withArgs(Roles.Manager, testAddress, ownerAddress, Roles.None) - }) - - it("should emit event after set enabled", async function () { - let testAddress = "0x0333000000000000000000000000000000000003" - let tx = await contract.setEnabled(testAddress) - let receipt = await tx.wait() - await expect(receipt) - .to.emit(contract, 'RoleSet') - .withArgs(Roles.Enabled, testAddress, ownerAddress, Roles.None) - }) - - it("should emit event after set none", async function () { - let testAddress = "0x0333000000000000000000000000000000000003" - let tx = await contract.setNone(testAddress) - let receipt = await tx.wait() - await expect(receipt) - .to.emit(contract, 'RoleSet') - .withArgs(Roles.None, testAddress, ownerAddress, Roles.Enabled) - }) -}) diff --git a/precompile/allowlist/allowlisttest/test_allowlist_events.go b/precompile/allowlist/allowlisttest/test_allowlist_events.go new file mode 100644 index 0000000000..b6fad627f1 --- /dev/null +++ b/precompile/allowlist/allowlisttest/test_allowlist_events.go @@ -0,0 +1,150 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package allowlisttest + +import ( + "testing" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/stretchr/testify/require" + + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/precompile/allowlist" + "github.com/ava-labs/subnet-evm/precompile/contracts/testutils" + + sim "github.com/ava-labs/subnet-evm/ethclient/simulated" + allowlistbindings "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest/bindings" +) + +// RunAllowListEventTests runs the standard AllowList event emission tests. +// This can be used by any precompile that uses the AllowList pattern. +func RunAllowListEventTests( + t *testing.T, + newBackend func(t *testing.T) *sim.Backend, + contractAddress common.Address, + adminAuth *bind.TransactOpts, + adminAddress common.Address, +) { + t.Helper() + + testKey, _ := crypto.GenerateKey() + testAddress := crypto.PubkeyToAddress(testKey.PublicKey) + + type testCase struct { + name string + testRun func(*allowlistbindings.IAllowList, *bind.TransactOpts, *sim.Backend, *testing.T, common.Address) + expectedEvents []allowlistbindings.IAllowListRoleSet + } + + testCases := []testCase{ + { + name: "should emit event after set admin", + testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { + tx, err := allowList.SetAdmin(auth, addr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + }, + expectedEvents: []allowlistbindings.IAllowListRoleSet{ + { + Role: allowlist.AdminRole.Big(), + Account: testAddress, + Sender: adminAddress, + OldRole: allowlist.NoRole.Big(), + }, + }, + }, + { + name: "should emit event after set manager", + testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { + tx, err := allowList.SetManager(auth, addr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + }, + expectedEvents: []allowlistbindings.IAllowListRoleSet{ + { + Role: allowlist.ManagerRole.Big(), + Account: testAddress, + Sender: adminAddress, + OldRole: allowlist.NoRole.Big(), + }, + }, + }, + { + name: "should emit event after set enabled", + testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { + tx, err := allowList.SetEnabled(auth, addr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + }, + expectedEvents: []allowlistbindings.IAllowListRoleSet{ + { + Role: allowlist.EnabledRole.Big(), + Account: testAddress, + Sender: adminAddress, + OldRole: allowlist.NoRole.Big(), + }, + }, + }, + { + name: "should emit event after set none", + testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { + // First set the address to Enabled so we can test setting it to None + tx, err := allowList.SetEnabled(auth, addr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + + tx, err = allowList.SetNone(auth, addr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + }, + expectedEvents: []allowlistbindings.IAllowListRoleSet{ + { + Role: allowlist.EnabledRole.Big(), + Account: testAddress, + Sender: adminAddress, + OldRole: allowlist.NoRole.Big(), + }, + { + Role: allowlist.NoRole.Big(), + Account: testAddress, + Sender: adminAddress, + OldRole: allowlist.EnabledRole.Big(), + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + require := require.New(t) + + backend := newBackend(t) + defer backend.Close() + + allowList, err := allowlistbindings.NewIAllowList(contractAddress, backend.Client()) + require.NoError(err) + + tc.testRun(allowList, adminAuth, backend, t, testAddress) + + iter, err := allowList.FilterRoleSet(nil, nil, nil, nil) + require.NoError(err) + defer iter.Close() + + // Verify event fields match expected values + for _, expectedEvent := range tc.expectedEvents { + require.True(iter.Next(), "expected to find RoleSet event") + event := iter.Event + require.Zero(expectedEvent.Role.Cmp(event.Role), "role mismatch") + require.Equal(expectedEvent.Account, event.Account, "account mismatch") + require.Equal(expectedEvent.Sender, event.Sender, "sender mismatch") + require.Zero(expectedEvent.OldRole.Cmp(event.OldRole), "oldRole mismatch") + } + + // Verify there are no more events + require.False(iter.Next(), "expected no more RoleSet events") + require.NoError(iter.Error()) + }) + } +} diff --git a/precompile/contracts/deployerallowlist/simulated_test.go b/precompile/contracts/deployerallowlist/simulated_test.go index fbc08ed87e..444aef4eca 100644 --- a/precompile/contracts/deployerallowlist/simulated_test.go +++ b/precompile/contracts/deployerallowlist/simulated_test.go @@ -217,131 +217,6 @@ func TestDeployerAllowList(t *testing.T) { } func TestIAllowList_Events(t *testing.T) { - chainID := params.TestChainConfig.ChainID - admin := testutils.NewAuth(t, adminKey, chainID) - testKey, _ := crypto.GenerateKey() - testAddress := crypto.PubkeyToAddress(testKey.PublicKey) - - type testCase struct { - name string - testRun func(*allowlistbindings.IAllowList, *bind.TransactOpts, *sim.Backend, *testing.T, common.Address) - expectedEvents []allowlistbindings.IAllowListRoleSet - } - - testCases := []testCase{ - { - name: "should emit event after set admin", - testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { - tx, err := allowList.SetAdmin(auth, addr) - require.NoError(t, err) - testutils.WaitReceipt(t, backend, tx) - }, - expectedEvents: []allowlistbindings.IAllowListRoleSet{ - { - Role: allowlist.AdminRole.Big(), - Account: testAddress, - Sender: adminAddress, - OldRole: allowlist.NoRole.Big(), - }, - }, - }, - { - name: "should emit event after set manager", - testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { - tx, err := allowList.SetManager(auth, addr) - require.NoError(t, err) - testutils.WaitReceipt(t, backend, tx) - }, - expectedEvents: []allowlistbindings.IAllowListRoleSet{ - { - Role: allowlist.ManagerRole.Big(), - Account: testAddress, - Sender: adminAddress, - OldRole: allowlist.NoRole.Big(), - }, - }, - }, - { - name: "should emit event after set enabled", - testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { - tx, err := allowList.SetEnabled(auth, addr) - require.NoError(t, err) - testutils.WaitReceipt(t, backend, tx) - }, - expectedEvents: []allowlistbindings.IAllowListRoleSet{ - { - Role: allowlist.EnabledRole.Big(), - Account: testAddress, - Sender: adminAddress, - OldRole: allowlist.NoRole.Big(), - }, - }, - }, - { - name: "should emit event after set none", - testRun: func(allowList *allowlistbindings.IAllowList, auth *bind.TransactOpts, backend *sim.Backend, t *testing.T, addr common.Address) { - // First set the address to Enabled so we can test setting it to None - tx, err := allowList.SetEnabled(auth, addr) - require.NoError(t, err) - testutils.WaitReceipt(t, backend, tx) - - tx, err = allowList.SetNone(auth, addr) - require.NoError(t, err) - testutils.WaitReceipt(t, backend, tx) - }, - expectedEvents: []allowlistbindings.IAllowListRoleSet{ - { - Role: allowlist.EnabledRole.Big(), - Account: testAddress, - Sender: adminAddress, - OldRole: allowlist.NoRole.Big(), - }, - { - Role: allowlist.NoRole.Big(), - Account: testAddress, - Sender: adminAddress, - OldRole: allowlist.EnabledRole.Big(), - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - require := require.New(t) - - backend := newBackendWithDeployerAllowList(t) - defer backend.Close() - - allowList, err := allowlistbindings.NewIAllowList(deployerallowlist.ContractAddress, backend.Client()) - require.NoError(err) - - tc.testRun(allowList, admin, backend, t, testAddress) - - // Filter for RoleSet events using FilterRoleSet - // This will filter for all RoleSet events. - iter, err := allowList.FilterRoleSet( - nil, - nil, - nil, - nil, - ) - require.NoError(err) - defer iter.Close() - - // Verify event fields match expected values - for _, expectedEvent := range tc.expectedEvents { - require.True(iter.Next(), "expected to find RoleSet event") - event := iter.Event - require.Zero(expectedEvent.Role.Cmp(event.Role), "role mismatch") - require.Equal(expectedEvent.Account, event.Account, "account mismatch") - require.Equal(expectedEvent.Sender, event.Sender, "sender mismatch") - require.Zero(expectedEvent.OldRole.Cmp(event.OldRole), "oldRole mismatch") - } - - // Verify there are no more events - require.False(iter.Next(), "expected no more RoleSet events") - require.NoError(iter.Error()) - }) - } + admin := testutils.NewAuth(t, adminKey, params.TestChainConfig.ChainID) + allowlisttest.RunAllowListEventTests(t, newBackendWithDeployerAllowList, deployerallowlist.ContractAddress, admin, adminAddress) } diff --git a/precompile/contracts/txallowlist/simulated_test.go b/precompile/contracts/txallowlist/simulated_test.go new file mode 100644 index 0000000000..23ee07d8a5 --- /dev/null +++ b/precompile/contracts/txallowlist/simulated_test.go @@ -0,0 +1,296 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package txallowlist_test + +import ( + "math/big" + "testing" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/stretchr/testify/require" + + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core" + "github.com/ava-labs/subnet-evm/params" + "github.com/ava-labs/subnet-evm/params/extras" + "github.com/ava-labs/subnet-evm/plugin/evm/customtypes" + "github.com/ava-labs/subnet-evm/precompile/allowlist" + "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" + "github.com/ava-labs/subnet-evm/precompile/contracts/testutils" + "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" + "github.com/ava-labs/subnet-evm/utils" + + sim "github.com/ava-labs/subnet-evm/ethclient/simulated" + allowlistbindings "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest/bindings" +) + +var ( + adminKey, _ = crypto.GenerateKey() + unprivilegedKey, _ = crypto.GenerateKey() + + adminAddress = crypto.PubkeyToAddress(adminKey.PublicKey) + unprivilegedAddress = crypto.PubkeyToAddress(unprivilegedKey.PublicKey) +) + +func TestMain(m *testing.M) { + // Ensure libevm extras are registered for tests. + core.RegisterExtras() + customtypes.Register() + params.RegisterExtras() + m.Run() +} + +func newBackendWithTxAllowList(t *testing.T) *sim.Backend { + t.Helper() + chainCfg := params.Copy(params.TestChainConfig) + // Enable TxAllowList at genesis with admin set to adminAddress. + params.GetExtra(&chainCfg).GenesisPrecompiles = extras.Precompiles{ + txallowlist.ConfigKey: txallowlist.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil), + } + return sim.NewBackend( + types.GenesisAlloc{ + adminAddress: {Balance: big.NewInt(1000000000000000000)}, + unprivilegedAddress: {Balance: big.NewInt(1000000000000000000)}, + }, + sim.WithChainConfig(&chainCfg), + ) +} + +// Helper functions to reduce test boilerplate + +func deployAllowListTest(t *testing.T, b *sim.Backend, auth *bind.TransactOpts) (common.Address, *allowlistbindings.AllowListTest) { + t.Helper() + addr, tx, contract, err := allowlistbindings.DeployAllowListTest(auth, b.Client(), txallowlist.ContractAddress) + require.NoError(t, err) + testutils.WaitReceiptSuccessful(t, b, tx) + return addr, contract +} + +func TestTxAllowList(t *testing.T) { + chainID := params.TestChainConfig.ChainID + admin := testutils.NewAuth(t, adminKey, chainID) + + type testCase struct { + name string + test func(t *testing.T, backend *sim.Backend, precompileIntf *allowlistbindings.IAllowList) + } + + testCases := []testCase{ + { + name: "should verify sender is admin", + test: func(t *testing.T, _ *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowlisttest.VerifyRole(t, allowList, adminAddress, allowlist.AdminRole) + }, + }, + { + name: "should verify new address has no role", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowListTestAddr, _ := deployAllowListTest(t, backend, admin) + allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.NoRole) + }, + }, + { + name: "should verify contract correctly reports admin status", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowListTestAddr, allowListTest := deployAllowListTest(t, backend, admin) + + allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.NoRole) + + isAdmin, err := allowListTest.IsAdmin(nil, allowListTestAddr) + require.NoError(t, err) + require.False(t, isAdmin) + + isAdmin, err = allowListTest.IsAdmin(nil, adminAddress) + require.NoError(t, err) + require.True(t, isAdmin) + }, + }, + { + name: "should allow admin to add contract as admin via precompile", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowListTestAddr, allowListTest := deployAllowListTest(t, backend, admin) + + allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.NoRole) + allowlisttest.SetAsAdmin(t, backend, allowList, admin, allowListTestAddr) + allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.AdminRole) + + isAdmin, err := allowListTest.IsAdmin(nil, allowListTestAddr) + require.NoError(t, err) + require.True(t, isAdmin) + }, + }, + { + name: "should allow admin to add enabled address via contract", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowListTestAddr, allowListTest := deployAllowListTest(t, backend, admin) + otherContractAddr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.NoRole) + allowlisttest.SetAsAdmin(t, backend, allowList, admin, allowListTestAddr) + allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.AdminRole) + + tx, err := allowListTest.SetEnabled(admin, otherContractAddr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + + isEnabled, err := allowListTest.IsEnabled(nil, otherContractAddr) + require.NoError(t, err) + require.True(t, isEnabled) + allowlisttest.VerifyRole(t, allowList, otherContractAddr, allowlist.EnabledRole) + }, + }, + { + name: "should not allow enabled address to add another enabled", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowListTestAddr, allowListTest := deployAllowListTest(t, backend, admin) + otherContractAddr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.SetAsEnabled(t, backend, allowList, admin, allowListTestAddr) + allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.EnabledRole) + + // Try to set another address as enabled - should fail + _, err := allowListTest.SetEnabled(admin, otherContractAddr) + require.ErrorContains(t, err, "execution reverted") + + allowlisttest.VerifyRole(t, allowList, otherContractAddr, allowlist.NoRole) + }, + }, + { + name: "should allow admin to revoke enabled", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowListTestAddr, allowListTest := deployAllowListTest(t, backend, admin) + enabledContractAddr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.SetAsAdmin(t, backend, allowList, admin, allowListTestAddr) + + tx, err := allowListTest.SetEnabled(admin, enabledContractAddr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + + isEnabled, err := allowListTest.IsEnabled(nil, enabledContractAddr) + require.NoError(t, err) + require.True(t, isEnabled) + + tx, err = allowListTest.Revoke(admin, enabledContractAddr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + + allowlisttest.VerifyRole(t, allowList, enabledContractAddr, allowlist.NoRole) + }, + }, + { + name: "should allow manager to add enabled", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + managerContractAddr, managerContract := deployAllowListTest(t, backend, admin) + enabledContractAddr, _ := deployAllowListTest(t, backend, admin) + + // Set contract as manager + allowlisttest.SetAsManager(t, backend, allowList, admin, managerContractAddr) + allowlisttest.VerifyRole(t, allowList, managerContractAddr, allowlist.ManagerRole) + + // Manager should be able to set enabled + tx, err := managerContract.SetEnabled(admin, enabledContractAddr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + + allowlisttest.VerifyRole(t, allowList, enabledContractAddr, allowlist.EnabledRole) + }, + }, + { + name: "should allow manager to revoke enabled", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + managerContractAddr, managerContract := deployAllowListTest(t, backend, admin) + enabledContractAddr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.SetAsManager(t, backend, allowList, admin, managerContractAddr) + + allowlisttest.SetAsEnabled(t, backend, allowList, admin, enabledContractAddr) + allowlisttest.VerifyRole(t, allowList, enabledContractAddr, allowlist.EnabledRole) + + tx, err := managerContract.Revoke(admin, enabledContractAddr) + require.NoError(t, err) + testutils.WaitReceipt(t, backend, tx) + + allowlisttest.VerifyRole(t, allowList, enabledContractAddr, allowlist.NoRole) + }, + }, + { + name: "should not allow manager to revoke admin", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + managerContractAddr, managerContract := deployAllowListTest(t, backend, admin) + adminContractAddr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.SetAsManager(t, backend, allowList, admin, managerContractAddr) + allowlisttest.SetAsAdmin(t, backend, allowList, admin, adminContractAddr) + + _, err := managerContract.Revoke(admin, adminContractAddr) + require.ErrorContains(t, err, "execution reverted") + + allowlisttest.VerifyRole(t, allowList, adminContractAddr, allowlist.AdminRole) + }, + }, + { + name: "should not allow manager to grant admin", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + managerContractAddr, managerContract := deployAllowListTest(t, backend, admin) + otherContractAddr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.SetAsManager(t, backend, allowList, admin, managerContractAddr) + + _, err := managerContract.SetAdmin(admin, otherContractAddr) + require.ErrorContains(t, err, "execution reverted") + + allowlisttest.VerifyRole(t, allowList, otherContractAddr, allowlist.NoRole) + }, + }, + { + name: "should not allow manager to grant manager", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + managerContractAddr, managerContract := deployAllowListTest(t, backend, admin) + otherContractAddr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.SetAsManager(t, backend, allowList, admin, managerContractAddr) + + _, err := managerContract.SetManager(admin, otherContractAddr) + require.ErrorContains(t, err, "execution reverted") + + allowlisttest.VerifyRole(t, allowList, otherContractAddr, allowlist.NoRole) + }, + }, + { + name: "should not allow manager to revoke manager", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + manager1Addr, manager1Contract := deployAllowListTest(t, backend, admin) + manager2Addr, _ := deployAllowListTest(t, backend, admin) + + allowlisttest.SetAsManager(t, backend, allowList, admin, manager1Addr) + allowlisttest.SetAsManager(t, backend, allowList, admin, manager2Addr) + + _, err := manager1Contract.Revoke(admin, manager2Addr) + require.ErrorContains(t, err, "execution reverted") + + allowlisttest.VerifyRole(t, allowList, manager2Addr, allowlist.ManagerRole) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + backend := newBackendWithTxAllowList(t) + defer backend.Close() + + allowList, err := allowlistbindings.NewIAllowList(txallowlist.ContractAddress, backend.Client()) + require.NoError(t, err) + + tc.test(t, backend, allowList) + }) + } +} + +func TestIAllowList_Events(t *testing.T) { + admin := testutils.NewAuth(t, adminKey, params.TestChainConfig.ChainID) + allowlisttest.RunAllowListEventTests(t, newBackendWithTxAllowList, txallowlist.ContractAddress, admin, adminAddress) +} diff --git a/tests/precompile/genesis/tx_allow_list.json b/tests/precompile/genesis/tx_allow_list.json deleted file mode 100644 index a2a1aaeb18..0000000000 --- a/tests/precompile/genesis/tx_allow_list.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "config": { - "chainId": 99999, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "feeConfig": { - "gasLimit": 20000000, - "minBaseFee": 1000000000, - "targetGas": 100000000, - "baseFeeChangeDenominator": 48, - "minBlockGasCost": 0, - "maxBlockGasCost": 10000000, - "targetBlockRate": 1, - "blockGasCostStep": 500000 - }, - "txAllowListConfig": { - "blockTimestamp": 0, - "adminAddresses": [ - "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC" - ] - } - }, - "alloc": { - "8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { - "balance": "0x52B7D2DCC80CD2E4000000" - }, - "0Fa8EA536Be85F32724D57A37758761B86416123": { - "balance": "0x52B7D2DCC80CD2E4000000" - } - }, - "nonce": "0x0", - "timestamp": "0x5FCB13D0", - "extraData": "0x00", - "gasLimit": "0x1312D00", - "difficulty": "0x0", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} diff --git a/tests/precompile/solidity/suites.go b/tests/precompile/solidity/suites.go index 63cdafedf3..d41077cfad 100644 --- a/tests/precompile/solidity/suites.go +++ b/tests/precompile/solidity/suites.go @@ -37,14 +37,6 @@ func RegisterAsyncTests() { // Each ginkgo It node specifies the name of the genesis file (in ./tests/precompile/genesis/) // to use to launch the subnet and the name of the TS test file to run on the subnet (in ./contracts/tests/) - ginkgo.It("tx allow list", ginkgo.Label("Precompile"), ginkgo.Label("TxAllowList"), func() { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - blockchainID := subnetsSuite.GetBlockchainID("tx_allow_list") - runDefaultHardhatTests(ctx, blockchainID, "tx_allow_list") - }) - ginkgo.It("fee manager", ginkgo.Label("Precompile"), ginkgo.Label("FeeManager"), func() { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() From 169f6f38ad988d795725c844ccaeeab3ea4e3915 Mon Sep 17 00:00:00 2001 From: Jonathan Oppenheimer Date: Wed, 3 Dec 2025 13:21:14 -0500 Subject: [PATCH 2/6] chore: delete old example --- .../contracts/test/ExampleTxAllowListTest.sol | 303 ------------------ 1 file changed, 303 deletions(-) delete mode 100644 contracts/contracts/test/ExampleTxAllowListTest.sol diff --git a/contracts/contracts/test/ExampleTxAllowListTest.sol b/contracts/contracts/test/ExampleTxAllowListTest.sol deleted file mode 100644 index debfa9de2a..0000000000 --- a/contracts/contracts/test/ExampleTxAllowListTest.sol +++ /dev/null @@ -1,303 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "../ExampleTxAllowList.sol"; -import "../AllowList.sol"; -import "../interfaces/IAllowList.sol"; -import "./AllowListTest.sol"; - -contract ExampleTxAllowListTest is AllowListTest { - address constant OTHER_ADDRESS = 0x0Fa8EA536Be85F32724D57A37758761B86416123; - - IAllowList allowList = IAllowList(TX_ALLOW_LIST); - - function setUp() public { - allowList.setNone(OTHER_ADDRESS); - } - - function step_contractOwnerIsAdmin() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - assertTrue(example.isAdmin(address(this))); - } - - function step_precompileHasDeployerAsAdmin() public { - assertRole(allowList.readAllowList(msg.sender), AllowList.Role.Admin); - } - - function step_newAddressHasNoRole() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - assertRole(allowList.readAllowList(address(example)), AllowList.Role.None); - } - - function step_noRoleIsNotAdmin() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList other = new ExampleTxAllowList(); - assertTrue(!example.isAdmin(address(other))); - } - - function step_exampleAllowListReturnsTestIsAdmin() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - assertTrue(example.isAdmin(address(this))); - } - - function step_fromOther() public { - // used as a noop to test transaction-success or failure, depending on wether the signer has been added to the tx-allow-list - } - - function step_enableOther() public { - assertRole(allowList.readAllowList(OTHER_ADDRESS), AllowList.Role.None); - allowList.setEnabled(OTHER_ADDRESS); - } - - function step_noRoleCannotEnableItself() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - - assertRole(allowList.readAllowList(address(example)), AllowList.Role.None); - - try example.setEnabled(address(example)) { - assertTrue(false, "setEnabled should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - } - - function step_addContractAsAdmin() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - address exampleAddress = address(example); - - assertRole(allowList.readAllowList(exampleAddress), AllowList.Role.None); - - allowList.setAdmin(exampleAddress); - - assertRole(allowList.readAllowList(exampleAddress), AllowList.Role.Admin); - - assertTrue(example.isAdmin(exampleAddress)); - } - - function step_enableThroughContract() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList other = new ExampleTxAllowList(); - address exampleAddress = address(example); - address otherAddress = address(other); - - assertTrue(!example.isEnabled(exampleAddress)); - assertTrue(!example.isEnabled(otherAddress)); - - allowList.setAdmin(exampleAddress); - - assertTrue(example.isEnabled(exampleAddress)); - assertTrue(!example.isEnabled(otherAddress)); - - example.setEnabled(otherAddress); - - assertTrue(example.isEnabled(exampleAddress)); - assertTrue(example.isEnabled(otherAddress)); - } - - function step_canDeploy() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - address exampleAddress = address(example); - - allowList.setEnabled(exampleAddress); - - example.deployContract(); - } - - function step_onlyAdminCanEnable() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList other = new ExampleTxAllowList(); - address exampleAddress = address(example); - address otherAddress = address(other); - - assertTrue(!example.isEnabled(exampleAddress)); - assertTrue(!example.isEnabled(otherAddress)); - - allowList.setEnabled(exampleAddress); - - assertTrue(example.isEnabled(exampleAddress)); - assertTrue(!example.isEnabled(otherAddress)); - - try example.setEnabled(otherAddress) { - assertTrue(false, "setEnabled should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - - // state should not have changed when setEnabled fails - assertTrue(!example.isEnabled(otherAddress)); - } - - function step_onlyAdminCanRevoke() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList other = new ExampleTxAllowList(); - address exampleAddress = address(example); - address otherAddress = address(other); - - assertTrue(!example.isEnabled(exampleAddress)); - assertTrue(!example.isEnabled(otherAddress)); - - allowList.setEnabled(exampleAddress); - allowList.setAdmin(otherAddress); - - assertTrue(example.isEnabled(exampleAddress) && !example.isAdmin(exampleAddress)); - assertTrue(example.isAdmin(otherAddress)); - - try example.revoke(otherAddress) { - assertTrue(false, "revoke should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - - // state should not have changed when revoke fails - assertTrue(example.isAdmin(otherAddress)); - } - - function step_adminCanRevoke() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList other = new ExampleTxAllowList(); - address exampleAddress = address(example); - address otherAddress = address(other); - - assertTrue(!example.isEnabled(exampleAddress)); - assertTrue(!example.isEnabled(otherAddress)); - - allowList.setAdmin(exampleAddress); - allowList.setAdmin(otherAddress); - - assertTrue(example.isAdmin(exampleAddress)); - assertTrue(other.isAdmin(otherAddress)); - - example.revoke(otherAddress); - assertTrue(!other.isEnabled(otherAddress)); - } - - function step_managerCanAllow() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList manager = new ExampleTxAllowList(); - address exampleAddress = address(example); - address managerAddress = address(manager); - - assertTrue(!example.isEnabled(exampleAddress)); - assertTrue(!example.isManager(managerAddress)); - - allowList.setManager(managerAddress); - - assertTrue(manager.isManager(managerAddress)); - - manager.setEnabled(exampleAddress); - assertTrue(example.isEnabled(exampleAddress)); - } - - function step_managerCanRevoke() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList manager = new ExampleTxAllowList(); - address exampleAddress = address(example); - address managerAddress = address(manager); - - assertTrue(!example.isAdmin(exampleAddress)); - assertTrue(!example.isManager(managerAddress)); - - allowList.setEnabled(exampleAddress); - allowList.setManager(managerAddress); - - assertTrue(example.isEnabled(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - - manager.revoke(exampleAddress); - assertTrue(!example.isEnabled(exampleAddress)); - } - - function step_managerCannotRevokeAdmin() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList manager = new ExampleTxAllowList(); - address exampleAddress = address(example); - address managerAddress = address(manager); - - assertTrue(!example.isAdmin(exampleAddress)); - assertTrue(!example.isManager(managerAddress)); - - allowList.setAdmin(exampleAddress); - allowList.setManager(managerAddress); - - assertTrue(example.isAdmin(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - - try manager.revoke(managerAddress) { - assertTrue(false, "revoke should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - - try manager.revoke(exampleAddress) { - assertTrue(false, "revoke should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - - // state should not have changed when revoke fails - assertTrue(example.isAdmin(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - } - - function step_managerCannotGrantAdmin() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList manager = new ExampleTxAllowList(); - address exampleAddress = address(example); - address managerAddress = address(manager); - - assertTrue(!example.isAdmin(exampleAddress)); - assertTrue(!example.isManager(managerAddress)); - - allowList.setManager(managerAddress); - - assertTrue(manager.isManager(managerAddress)); - - try manager.setAdmin(exampleAddress) { - assertTrue(false, "setAdmin should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - - // state should not have changed when setAdmin fails - assertTrue(!example.isAdmin(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - } - - function step_managerCannotGrantManager() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList manager = new ExampleTxAllowList(); - address exampleAddress = address(example); - address managerAddress = address(manager); - - allowList.setManager(managerAddress); - - assertTrue(!example.isManager(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - - try manager.setManager(exampleAddress) { - assertTrue(false, "setManager should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - - // state should not have changed when setManager fails - assertTrue(!example.isManager(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - } - - function step_managerCannotRevokeManager() public { - ExampleTxAllowList example = new ExampleTxAllowList(); - ExampleTxAllowList manager = new ExampleTxAllowList(); - address exampleAddress = address(example); - address managerAddress = address(manager); - - allowList.setManager(exampleAddress); - allowList.setManager(managerAddress); - - assertTrue(example.isManager(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - - try manager.revoke(exampleAddress) { - assertTrue(false, "revoke should fail"); - } catch {} // TODO should match on an error to make sure that this is failing in the way that's expected - - // state should not have changed when revoke fails - assertTrue(example.isManager(exampleAddress)); - assertTrue(manager.isManager(managerAddress)); - } - - function step_managerCanDeploy() public { - ExampleTxAllowList manager = new ExampleTxAllowList(); - address managerAddress = address(manager); - - allowList.setManager(managerAddress); - - manager.deployContract(); - } -} From bb219313614640b9e5d878d351e67465b9b8b169 Mon Sep 17 00:00:00 2001 From: Jonathan Oppenheimer Date: Thu, 4 Dec 2025 11:59:11 -0500 Subject: [PATCH 3/6] test: add should not let non-enabled address submit txs --- .../allowlisttest/test_allowlist_events.go | 11 +++++------ .../contracts/deployerallowlist/simulated_test.go | 2 +- precompile/contracts/txallowlist/simulated_test.go | 13 ++++++++++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/precompile/allowlist/allowlisttest/test_allowlist_events.go b/precompile/allowlist/allowlisttest/test_allowlist_events.go index b6fad627f1..07cb4b7d58 100644 --- a/precompile/allowlist/allowlisttest/test_allowlist_events.go +++ b/precompile/allowlist/allowlisttest/test_allowlist_events.go @@ -25,7 +25,6 @@ func RunAllowListEventTests( newBackend func(t *testing.T) *sim.Backend, contractAddress common.Address, adminAuth *bind.TransactOpts, - adminAddress common.Address, ) { t.Helper() @@ -50,7 +49,7 @@ func RunAllowListEventTests( { Role: allowlist.AdminRole.Big(), Account: testAddress, - Sender: adminAddress, + Sender: adminAuth.From, OldRole: allowlist.NoRole.Big(), }, }, @@ -66,7 +65,7 @@ func RunAllowListEventTests( { Role: allowlist.ManagerRole.Big(), Account: testAddress, - Sender: adminAddress, + Sender: adminAuth.From, OldRole: allowlist.NoRole.Big(), }, }, @@ -82,7 +81,7 @@ func RunAllowListEventTests( { Role: allowlist.EnabledRole.Big(), Account: testAddress, - Sender: adminAddress, + Sender: adminAuth.From, OldRole: allowlist.NoRole.Big(), }, }, @@ -103,13 +102,13 @@ func RunAllowListEventTests( { Role: allowlist.EnabledRole.Big(), Account: testAddress, - Sender: adminAddress, + Sender: adminAuth.From, OldRole: allowlist.NoRole.Big(), }, { Role: allowlist.NoRole.Big(), Account: testAddress, - Sender: adminAddress, + Sender: adminAuth.From, OldRole: allowlist.EnabledRole.Big(), }, }, diff --git a/precompile/contracts/deployerallowlist/simulated_test.go b/precompile/contracts/deployerallowlist/simulated_test.go index 444aef4eca..fa26857201 100644 --- a/precompile/contracts/deployerallowlist/simulated_test.go +++ b/precompile/contracts/deployerallowlist/simulated_test.go @@ -218,5 +218,5 @@ func TestDeployerAllowList(t *testing.T) { func TestIAllowList_Events(t *testing.T) { admin := testutils.NewAuth(t, adminKey, params.TestChainConfig.ChainID) - allowlisttest.RunAllowListEventTests(t, newBackendWithDeployerAllowList, deployerallowlist.ContractAddress, admin, adminAddress) + allowlisttest.RunAllowListEventTests(t, newBackendWithDeployerAllowList, deployerallowlist.ContractAddress, admin) } diff --git a/precompile/contracts/txallowlist/simulated_test.go b/precompile/contracts/txallowlist/simulated_test.go index 23ee07d8a5..ccea4d378e 100644 --- a/precompile/contracts/txallowlist/simulated_test.go +++ b/precompile/contracts/txallowlist/simulated_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/customtypes" + "github.com/ava-labs/subnet-evm/plugin/evm/vmerrors" "github.com/ava-labs/subnet-evm/precompile/allowlist" "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" "github.com/ava-labs/subnet-evm/precompile/contracts/testutils" @@ -72,6 +73,7 @@ func deployAllowListTest(t *testing.T, b *sim.Backend, auth *bind.TransactOpts) func TestTxAllowList(t *testing.T) { chainID := params.TestChainConfig.ChainID admin := testutils.NewAuth(t, adminKey, chainID) + unprivileged := testutils.NewAuth(t, unprivilegedKey, chainID) type testCase struct { name string @@ -92,6 +94,15 @@ func TestTxAllowList(t *testing.T) { allowlisttest.VerifyRole(t, allowList, allowListTestAddr, allowlist.NoRole) }, }, + { + name: "should not let non-enabled address submit txs", + test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { + allowlisttest.VerifyRole(t, allowList, unprivilegedAddress, allowlist.NoRole) + + _, _, _, err := allowlistbindings.DeployAllowListTest(unprivileged, backend.Client(), txallowlist.ContractAddress) + require.ErrorContains(t, err, vmerrors.ErrSenderAddressNotAllowListed.Error()) //nolint:forbidigo // upstream error wrapped as string + }, + }, { name: "should verify contract correctly reports admin status", test: func(t *testing.T, backend *sim.Backend, allowList *allowlistbindings.IAllowList) { @@ -292,5 +303,5 @@ func TestTxAllowList(t *testing.T) { func TestIAllowList_Events(t *testing.T) { admin := testutils.NewAuth(t, adminKey, params.TestChainConfig.ChainID) - allowlisttest.RunAllowListEventTests(t, newBackendWithTxAllowList, txallowlist.ContractAddress, admin, adminAddress) + allowlisttest.RunAllowListEventTests(t, newBackendWithTxAllowList, txallowlist.ContractAddress, admin) } From 1e0d2fe35d16e36be08f980c249168d3f839c54a Mon Sep 17 00:00:00 2001 From: Jonathan Oppenheimer Date: Thu, 4 Dec 2025 12:03:57 -0500 Subject: [PATCH 4/6] style: ignore lint error for now --- precompile/contracts/txallowlist/simulated_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/precompile/contracts/txallowlist/simulated_test.go b/precompile/contracts/txallowlist/simulated_test.go index ccea4d378e..0c0b1afe3e 100644 --- a/precompile/contracts/txallowlist/simulated_test.go +++ b/precompile/contracts/txallowlist/simulated_test.go @@ -100,7 +100,7 @@ func TestTxAllowList(t *testing.T) { allowlisttest.VerifyRole(t, allowList, unprivilegedAddress, allowlist.NoRole) _, _, _, err := allowlistbindings.DeployAllowListTest(unprivileged, backend.Client(), txallowlist.ContractAddress) - require.ErrorContains(t, err, vmerrors.ErrSenderAddressNotAllowListed.Error()) //nolint:forbidigo // upstream error wrapped as string + require.ErrorContains(t, err, vmerrors.ErrSenderAddressNotAllowListed.Error()) // //nolint:forbidigo // upstream error wrapped as string }, }, { From 1069395169e572c5253c9832fc91e72809aeabcf Mon Sep 17 00:00:00 2001 From: Jonathan Oppenheimer Date: Thu, 4 Dec 2025 14:48:10 -0500 Subject: [PATCH 5/6] test: add helper function for backend --- .../allowlisttest/test_allowlist_events.go | 6 +++-- .../deployerallowlist/simulated_test.go | 27 +++---------------- .../contracts/feemanager/simulated_test.go | 27 +++---------------- .../contracts/nativeminter/simulated_test.go | 27 +++---------------- .../contracts/testutils/simulated_helpers.go | 21 +++++++++++++++ .../contracts/txallowlist/simulated_test.go | 27 +++---------------- 6 files changed, 41 insertions(+), 94 deletions(-) diff --git a/precompile/allowlist/allowlisttest/test_allowlist_events.go b/precompile/allowlist/allowlisttest/test_allowlist_events.go index 07cb4b7d58..178821bc4b 100644 --- a/precompile/allowlist/allowlisttest/test_allowlist_events.go +++ b/precompile/allowlist/allowlisttest/test_allowlist_events.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/precompile/allowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/testutils" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" sim "github.com/ava-labs/subnet-evm/ethclient/simulated" allowlistbindings "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest/bindings" @@ -22,9 +23,10 @@ import ( // This can be used by any precompile that uses the AllowList pattern. func RunAllowListEventTests( t *testing.T, - newBackend func(t *testing.T) *sim.Backend, + precompileCfg precompileconfig.Config, contractAddress common.Address, adminAuth *bind.TransactOpts, + fundedAddrs ...common.Address, ) { t.Helper() @@ -119,7 +121,7 @@ func RunAllowListEventTests( t.Run(tc.name, func(t *testing.T) { require := require.New(t) - backend := newBackend(t) + backend := testutils.NewBackendWithPrecompile(t, precompileCfg, fundedAddrs...) defer backend.Close() allowList, err := allowlistbindings.NewIAllowList(contractAddress, backend.Client()) diff --git a/precompile/contracts/deployerallowlist/simulated_test.go b/precompile/contracts/deployerallowlist/simulated_test.go index fa26857201..738fc8e4c2 100644 --- a/precompile/contracts/deployerallowlist/simulated_test.go +++ b/precompile/contracts/deployerallowlist/simulated_test.go @@ -4,11 +4,9 @@ package deployerallowlist_test import ( - "math/big" "testing" "github.com/ava-labs/libevm/common" - "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" @@ -16,7 +14,6 @@ import ( "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/customtypes" "github.com/ava-labs/subnet-evm/precompile/allowlist" "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" @@ -44,24 +41,6 @@ func TestMain(m *testing.M) { m.Run() } -func newBackendWithDeployerAllowList(t *testing.T) *sim.Backend { - t.Helper() - chainCfg := params.Copy(params.TestChainConfig) - // Enable ContractDeployerAllowList at genesis with admin set to adminAddress. - params.GetExtra(&chainCfg).GenesisPrecompiles = extras.Precompiles{ - deployerallowlist.ConfigKey: deployerallowlist.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil), - } - return sim.NewBackend( - types.GenesisAlloc{ - adminAddress: {Balance: big.NewInt(1000000000000000000)}, - unprivilegedAddress: {Balance: big.NewInt(1000000000000000000)}, - }, - sim.WithChainConfig(&chainCfg), - ) -} - -// Helper functions to reduce test boilerplate - func deployAllowListTest(t *testing.T, b *sim.Backend, auth *bind.TransactOpts) (common.Address, *allowlistbindings.AllowListTest) { t.Helper() addr, tx, contract, err := allowlistbindings.DeployAllowListTest(auth, b.Client(), deployerallowlist.ContractAddress) @@ -203,9 +182,10 @@ func TestDeployerAllowList(t *testing.T) { }, } + precompileCfg := deployerallowlist.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - backend := newBackendWithDeployerAllowList(t) + backend := testutils.NewBackendWithPrecompile(t, precompileCfg, adminAddress, unprivilegedAddress) defer backend.Close() allowList, err := allowlistbindings.NewIAllowList(deployerallowlist.ContractAddress, backend.Client()) @@ -217,6 +197,7 @@ func TestDeployerAllowList(t *testing.T) { } func TestIAllowList_Events(t *testing.T) { + precompileCfg := deployerallowlist.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil) admin := testutils.NewAuth(t, adminKey, params.TestChainConfig.ChainID) - allowlisttest.RunAllowListEventTests(t, newBackendWithDeployerAllowList, deployerallowlist.ContractAddress, admin) + allowlisttest.RunAllowListEventTests(t, precompileCfg, deployerallowlist.ContractAddress, admin, adminAddress, unprivilegedAddress) } diff --git a/precompile/contracts/feemanager/simulated_test.go b/precompile/contracts/feemanager/simulated_test.go index 739132351c..2d85a62e13 100644 --- a/precompile/contracts/feemanager/simulated_test.go +++ b/precompile/contracts/feemanager/simulated_test.go @@ -16,7 +16,6 @@ import ( "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/customtypes" "github.com/ava-labs/subnet-evm/precompile/allowlist" "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" @@ -68,26 +67,6 @@ func TestMain(m *testing.M) { m.Run() } -func newBackendWithFeeManager(t *testing.T) *sim.Backend { - t.Helper() - chainCfg := params.Copy(params.TestChainConfig) - - // Enable FeeManager at genesis with admin set to adminAddress and initial fee config. - params.GetExtra(&chainCfg).GenesisPrecompiles = extras.Precompiles{ - feemanager.ConfigKey: feemanager.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil, &genesisFeeConfig), - } - - return sim.NewBackend( - types.GenesisAlloc{ - adminAddress: {Balance: big.NewInt(1000000000000000000)}, - unprivilegedAddress: {Balance: big.NewInt(1000000000000000000)}, - }, - sim.WithChainConfig(&chainCfg), - ) -} - -// Helper functions to reduce test boilerplate - func deployFeeManagerTest(t *testing.T, b *sim.Backend, auth *bind.TransactOpts) (common.Address, *feemanagerbindings.FeeManagerTest) { t.Helper() addr, tx, contract, err := feemanagerbindings.DeployFeeManagerTest(auth, b.Client(), feemanager.ContractAddress) @@ -252,9 +231,10 @@ func TestFeeManager(t *testing.T) { }, } + precompileCfg := feemanager.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil, &genesisFeeConfig) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - backend := newBackendWithFeeManager(t) + backend := testutils.NewBackendWithPrecompile(t, precompileCfg, adminAddress, unprivilegedAddress) defer backend.Close() feeManager, err := feemanagerbindings.NewIFeeManager(feemanager.ContractAddress, backend.Client()) @@ -269,7 +249,8 @@ func TestIFeeManager_Events(t *testing.T) { chainID := params.TestChainConfig.ChainID admin := testutils.NewAuth(t, adminKey, chainID) - backend := newBackendWithFeeManager(t) + precompileCfg := feemanager.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil, &genesisFeeConfig) + backend := testutils.NewBackendWithPrecompile(t, precompileCfg, adminAddress, unprivilegedAddress) defer backend.Close() feeManager, err := feemanagerbindings.NewIFeeManager(feemanager.ContractAddress, backend.Client()) diff --git a/precompile/contracts/nativeminter/simulated_test.go b/precompile/contracts/nativeminter/simulated_test.go index 54b94f1be3..546ed4b41e 100644 --- a/precompile/contracts/nativeminter/simulated_test.go +++ b/precompile/contracts/nativeminter/simulated_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/ava-labs/libevm/common" - "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" @@ -16,7 +15,6 @@ import ( "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/customtypes" "github.com/ava-labs/subnet-evm/precompile/allowlist" "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" @@ -44,25 +42,6 @@ func TestMain(m *testing.M) { m.Run() } -func newBackendWithNativeMinter(t *testing.T) *sim.Backend { - t.Helper() - chainCfg := params.Copy(params.TestChainConfig) - - // Enable ContractNativeMinter at genesis with admin set to adminAddress. - params.GetExtra(&chainCfg).GenesisPrecompiles = extras.Precompiles{ - nativeminter.ConfigKey: nativeminter.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil, nil), - } - return sim.NewBackend( - types.GenesisAlloc{ - adminAddress: {Balance: big.NewInt(1000000000000000000)}, - unprivilegedAddress: {Balance: big.NewInt(1000000000000000000)}, - }, - sim.WithChainConfig(&chainCfg), - ) -} - -// Helper functions to reduce test boilerplate - func deployNativeMinterTest(t *testing.T, b *sim.Backend, auth *bind.TransactOpts) (common.Address, *nativeminterbindings.NativeMinterTest) { t.Helper() addr, tx, contract, err := nativeminterbindings.DeployNativeMinterTest(auth, b.Client(), nativeminter.ContractAddress) @@ -164,9 +143,10 @@ func TestNativeMinter(t *testing.T) { }, } + precompileCfg := nativeminter.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil, nil) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - backend := newBackendWithNativeMinter(t) + backend := testutils.NewBackendWithPrecompile(t, precompileCfg, adminAddress, unprivilegedAddress) defer backend.Close() nativeMinter, err := nativeminterbindings.NewINativeMinter(nativeminter.ContractAddress, backend.Client()) @@ -183,7 +163,8 @@ func TestINativeMinter_Events(t *testing.T) { testKey, _ := crypto.GenerateKey() testAddress := crypto.PubkeyToAddress(testKey.PublicKey) - backend := newBackendWithNativeMinter(t) + precompileCfg := nativeminter.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil, nil) + backend := testutils.NewBackendWithPrecompile(t, precompileCfg, adminAddress, unprivilegedAddress) defer backend.Close() nativeMinter, err := nativeminterbindings.NewINativeMinter(nativeminter.ContractAddress, backend.Client()) diff --git a/precompile/contracts/testutils/simulated_helpers.go b/precompile/contracts/testutils/simulated_helpers.go index 739a4b4134..8cce014eed 100644 --- a/precompile/contracts/testutils/simulated_helpers.go +++ b/precompile/contracts/testutils/simulated_helpers.go @@ -8,10 +8,14 @@ import ( "math/big" "testing" + "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/params" + "github.com/ava-labs/subnet-evm/params/extras" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" sim "github.com/ava-labs/subnet-evm/ethclient/simulated" ) @@ -24,6 +28,23 @@ func NewAuth(t *testing.T, key *ecdsa.PrivateKey, chainID *big.Int) *bind.Transa return auth } +// NewBackendWithPrecompile creates a simulated backend with the given precompile enabled +// at genesis and funds the specified addresses with 1 ETH each. +func NewBackendWithPrecompile(t *testing.T, precompileCfg precompileconfig.Config, fundedAddrs ...common.Address) *sim.Backend { + t.Helper() + chainCfg := params.Copy(params.TestChainConfig) + params.GetExtra(&chainCfg).GenesisPrecompiles = extras.Precompiles{ + precompileCfg.Key(): precompileCfg, + } + + genesisAlloc := make(types.GenesisAlloc) + for _, addr := range fundedAddrs { + genesisAlloc[addr] = types.Account{Balance: big.NewInt(1000000000000000000)} + } + + return sim.NewBackend(genesisAlloc, sim.WithChainConfig(&chainCfg)) +} + // WaitReceipt commits the simulated backend and waits for the transaction receipt. func WaitReceipt(t *testing.T, b *sim.Backend, tx *types.Transaction) *types.Receipt { t.Helper() diff --git a/precompile/contracts/txallowlist/simulated_test.go b/precompile/contracts/txallowlist/simulated_test.go index 0c0b1afe3e..83d284fd2c 100644 --- a/precompile/contracts/txallowlist/simulated_test.go +++ b/precompile/contracts/txallowlist/simulated_test.go @@ -4,18 +4,15 @@ package txallowlist_test import ( - "math/big" "testing" "github.com/ava-labs/libevm/common" - "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/customtypes" "github.com/ava-labs/subnet-evm/plugin/evm/vmerrors" "github.com/ava-labs/subnet-evm/precompile/allowlist" @@ -44,24 +41,6 @@ func TestMain(m *testing.M) { m.Run() } -func newBackendWithTxAllowList(t *testing.T) *sim.Backend { - t.Helper() - chainCfg := params.Copy(params.TestChainConfig) - // Enable TxAllowList at genesis with admin set to adminAddress. - params.GetExtra(&chainCfg).GenesisPrecompiles = extras.Precompiles{ - txallowlist.ConfigKey: txallowlist.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil), - } - return sim.NewBackend( - types.GenesisAlloc{ - adminAddress: {Balance: big.NewInt(1000000000000000000)}, - unprivilegedAddress: {Balance: big.NewInt(1000000000000000000)}, - }, - sim.WithChainConfig(&chainCfg), - ) -} - -// Helper functions to reduce test boilerplate - func deployAllowListTest(t *testing.T, b *sim.Backend, auth *bind.TransactOpts) (common.Address, *allowlistbindings.AllowListTest) { t.Helper() addr, tx, contract, err := allowlistbindings.DeployAllowListTest(auth, b.Client(), txallowlist.ContractAddress) @@ -288,9 +267,10 @@ func TestTxAllowList(t *testing.T) { }, } + precompileCfg := txallowlist.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - backend := newBackendWithTxAllowList(t) + backend := testutils.NewBackendWithPrecompile(t, precompileCfg, adminAddress, unprivilegedAddress) defer backend.Close() allowList, err := allowlistbindings.NewIAllowList(txallowlist.ContractAddress, backend.Client()) @@ -302,6 +282,7 @@ func TestTxAllowList(t *testing.T) { } func TestIAllowList_Events(t *testing.T) { + precompileCfg := txallowlist.NewConfig(utils.NewUint64(0), []common.Address{adminAddress}, nil, nil) admin := testutils.NewAuth(t, adminKey, params.TestChainConfig.ChainID) - allowlisttest.RunAllowListEventTests(t, newBackendWithTxAllowList, txallowlist.ContractAddress, admin) + allowlisttest.RunAllowListEventTests(t, precompileCfg, txallowlist.ContractAddress, admin, adminAddress, unprivilegedAddress) } From f519cccd5af7362e7bc9e5f7178f956a36473559 Mon Sep 17 00:00:00 2001 From: Jonathan Oppenheimer Date: Thu, 4 Dec 2025 15:10:15 -0500 Subject: [PATCH 6/6] chore: lint --- precompile/contracts/txallowlist/simulated_test.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/precompile/contracts/txallowlist/simulated_test.go b/precompile/contracts/txallowlist/simulated_test.go index 83d284fd2c..20a6a98028 100644 --- a/precompile/contracts/txallowlist/simulated_test.go +++ b/precompile/contracts/txallowlist/simulated_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/vm" "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" @@ -143,7 +144,7 @@ func TestTxAllowList(t *testing.T) { // Try to set another address as enabled - should fail _, err := allowListTest.SetEnabled(admin, otherContractAddr) - require.ErrorContains(t, err, "execution reverted") + require.ErrorContains(t, err, vm.ErrExecutionReverted.Error()) //nolint:forbidigo // upstream error wrapped as string allowlisttest.VerifyRole(t, allowList, otherContractAddr, allowlist.NoRole) }, @@ -217,7 +218,7 @@ func TestTxAllowList(t *testing.T) { allowlisttest.SetAsAdmin(t, backend, allowList, admin, adminContractAddr) _, err := managerContract.Revoke(admin, adminContractAddr) - require.ErrorContains(t, err, "execution reverted") + require.ErrorContains(t, err, vm.ErrExecutionReverted.Error()) //nolint:forbidigo // upstream error wrapped as string allowlisttest.VerifyRole(t, allowList, adminContractAddr, allowlist.AdminRole) }, @@ -231,7 +232,7 @@ func TestTxAllowList(t *testing.T) { allowlisttest.SetAsManager(t, backend, allowList, admin, managerContractAddr) _, err := managerContract.SetAdmin(admin, otherContractAddr) - require.ErrorContains(t, err, "execution reverted") + require.ErrorContains(t, err, vm.ErrExecutionReverted.Error()) //nolint:forbidigo // upstream error wrapped as string allowlisttest.VerifyRole(t, allowList, otherContractAddr, allowlist.NoRole) }, @@ -245,7 +246,7 @@ func TestTxAllowList(t *testing.T) { allowlisttest.SetAsManager(t, backend, allowList, admin, managerContractAddr) _, err := managerContract.SetManager(admin, otherContractAddr) - require.ErrorContains(t, err, "execution reverted") + require.ErrorContains(t, err, vm.ErrExecutionReverted.Error()) //nolint:forbidigo // upstream error wrapped as string allowlisttest.VerifyRole(t, allowList, otherContractAddr, allowlist.NoRole) }, @@ -260,7 +261,7 @@ func TestTxAllowList(t *testing.T) { allowlisttest.SetAsManager(t, backend, allowList, admin, manager2Addr) _, err := manager1Contract.Revoke(admin, manager2Addr) - require.ErrorContains(t, err, "execution reverted") + require.ErrorContains(t, err, vm.ErrExecutionReverted.Error()) //nolint:forbidigo // upstream error wrapped as string allowlisttest.VerifyRole(t, allowList, manager2Addr, allowlist.ManagerRole) },