Skip to content
This repository was archived by the owner on Dec 16, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions core/TrieStressTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
pragma solidity ^0.8.0;

contract TrieStressTest {
bytes32[] private data;
bytes32[] private data;

function writeValues(uint value) public {
bytes32 dataToPush = bytes32(uint256(uint160(msg.sender)) << 96);
for (uint i = 0; i < value; i++) {
data.push(dataToPush);
function writeValues(uint value) public {
bytes32 dataToPush = bytes32(uint256(uint160(msg.sender)) << 96);
for (uint i = 0; i < value; i++) {
data.push(dataToPush);
}
}
}

function getLength() public view returns (uint) {
return data.length;
}
function getLength() public view returns (uint) {
return data.length;
}

function getData(uint index) public view returns (bytes32) {
require(index < data.length, "Index out of bound");
return data[index];
}
function getData(uint index) public view returns (bytes32) {
require(index < data.length, "Index out of bound");
return data[index];
}
}
110 changes: 60 additions & 50 deletions plugin/evm/ExampleWarp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,64 @@ pragma experimental ABIEncoderV2;
import "precompile/contracts/warp/warpbindings/IWarpMessenger.sol";

contract ExampleWarp {
address constant WARP_ADDRESS = 0x0200000000000000000000000000000000000005;
IWarpMessenger warp = IWarpMessenger(WARP_ADDRESS);

// sendWarpMessage sends a warp message containing the payload
function sendWarpMessage(bytes calldata payload) external {
warp.sendWarpMessage(payload);
}

// validateWarpMessage retrieves the warp message attached to the transaction and verifies all of its attributes.
function validateWarpMessage(
uint32 index,
bytes32 sourceChainID,
address originSenderAddress,
bytes calldata payload
) external view {
(WarpMessage memory message, bool valid) = warp.getVerifiedWarpMessage(index);
require(valid);
require(message.sourceChainID == sourceChainID);
require(message.originSenderAddress == originSenderAddress);
require(keccak256(message.payload) == keccak256(payload));
}

function validateInvalidWarpMessage(uint32 index) external view {
(WarpMessage memory message, bool valid) = warp.getVerifiedWarpMessage(index);
require(!valid);
require(message.sourceChainID == bytes32(0));
require(message.originSenderAddress == address(0));
require(keccak256(message.payload) == keccak256(bytes("")));
}

// validateWarpBlockHash retrieves the warp block hash attached to the transaction and verifies it matches the
// expected block hash.
function validateWarpBlockHash(uint32 index, bytes32 sourceChainID, bytes32 blockHash) external view {
(WarpBlockHash memory warpBlockHash, bool valid) = warp.getVerifiedWarpBlockHash(index);
require(valid);
require(warpBlockHash.sourceChainID == sourceChainID);
require(warpBlockHash.blockHash == blockHash);
}

function validateInvalidWarpBlockHash(uint32 index) external view {
(WarpBlockHash memory warpBlockHash, bool valid) = warp.getVerifiedWarpBlockHash(index);
require(!valid);
require(warpBlockHash.sourceChainID == bytes32(0));
require(warpBlockHash.blockHash == bytes32(0));
}

// validateGetBlockchainID checks that the blockchainID returned by warp matches the argument
function validateGetBlockchainID(bytes32 blockchainID) external view {
require(blockchainID == warp.getBlockchainID());
}
address constant WARP_ADDRESS = 0x0200000000000000000000000000000000000005;
IWarpMessenger warp = IWarpMessenger(WARP_ADDRESS);

// sendWarpMessage sends a warp message containing the payload
function sendWarpMessage(bytes calldata payload) external {
warp.sendWarpMessage(payload);
}

// validateWarpMessage retrieves the warp message attached to the transaction and verifies all of its attributes.
function validateWarpMessage(
uint32 index,
bytes32 sourceChainID,
address originSenderAddress,
bytes calldata payload
) external view {
(WarpMessage memory message, bool valid) = warp.getVerifiedWarpMessage(
index
);
require(valid);
require(message.sourceChainID == sourceChainID);
require(message.originSenderAddress == originSenderAddress);
require(keccak256(message.payload) == keccak256(payload));
}

function validateInvalidWarpMessage(uint32 index) external view {
(WarpMessage memory message, bool valid) = warp.getVerifiedWarpMessage(
index
);
require(!valid);
require(message.sourceChainID == bytes32(0));
require(message.originSenderAddress == address(0));
require(keccak256(message.payload) == keccak256(bytes("")));
}

// validateWarpBlockHash retrieves the warp block hash attached to the transaction and verifies it matches the
// expected block hash.
function validateWarpBlockHash(
uint32 index,
bytes32 sourceChainID,
bytes32 blockHash
) external view {
(WarpBlockHash memory warpBlockHash, bool valid) = warp
.getVerifiedWarpBlockHash(index);
require(valid);
require(warpBlockHash.sourceChainID == sourceChainID);
require(warpBlockHash.blockHash == blockHash);
}

function validateInvalidWarpBlockHash(uint32 index) external view {
(WarpBlockHash memory warpBlockHash, bool valid) = warp
.getVerifiedWarpBlockHash(index);
require(!valid);
require(warpBlockHash.sourceChainID == bytes32(0));
require(warpBlockHash.blockHash == bytes32(0));
}

// validateGetBlockchainID checks that the blockchainID returned by warp matches the argument
function validateGetBlockchainID(bytes32 blockchainID) external view {
require(blockchainID == warp.getBlockchainID());
}
}
23 changes: 14 additions & 9 deletions precompile/allowlist/IAllowList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@
pragma solidity ^0.8.24;

interface IAllowList {
event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole);
event RoleSet(
uint256 indexed role,
address indexed account,
address indexed sender,
uint256 oldRole
);

// Set [addr] to have the admin role over the precompile contract.
function setAdmin(address addr) external;
// Set [addr] to have the admin role over the precompile contract.
function setAdmin(address addr) external;

// Set [addr] to be enabled on the precompile contract.
function setEnabled(address addr) external;
// Set [addr] to be enabled on the precompile contract.
function setEnabled(address addr) external;

// Set [addr] to have the manager role over the precompile contract.
function setManager(address addr) external;
// Set [addr] to have the manager role over the precompile contract.
function setManager(address addr) external;

// Set [addr] to have no role for the precompile contract.
function setNone(address addr) external;
// Set [addr] to have no role for the precompile contract.
function setNone(address addr) external;

// Read the status of [addr].
function readAllowList(address addr) external view returns (uint256 role);
Expand Down
2 changes: 1 addition & 1 deletion precompile/allowlist/allowlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var (
ErrCannotModifyAllowList = errors.New("cannot modify allow list")

// AllowListRawABI contains the raw ABI of AllowList library interface.
//go:embed allowlist.abi
//go:embed IAllowList.abi
AllowListRawABI string

AllowListABI = contract.ParseABI(AllowListRawABI)
Expand Down
4 changes: 2 additions & 2 deletions precompile/allowlist/allowlisttest/bindings/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
package bindings

// Step 1: Compile interface to generate ABI at top level
//go:generate sh -c "solc-v0.8.30 -o ../.. --overwrite --abi --pretty-json --evm-version cancun ../../IAllowList.sol && mv ../../IAllowList.abi ../../allowlist.abi"
//go:generate sh -c "solc-v0.8.30 -o ../.. --overwrite --abi --pretty-json --evm-version cancun ../../IAllowList.sol"
// Step 2: Compile test contracts to generate ABI and bin files
//go:generate solc-v0.8.30 -o artifacts --overwrite --abi --bin --base-path . --metadata-hash none precompile/=../../../ --evm-version cancun AllowListTest.sol
// Step 3: Generate Go bindings from the compiled artifacts
//go:generate go run github.com/ava-labs/libevm/cmd/abigen --pkg bindings --type IAllowList --abi ../../allowlist.abi --bin artifacts/IAllowList.bin --out gen_allowlist_binding.go
//go:generate go run github.com/ava-labs/libevm/cmd/abigen --pkg bindings --type IAllowList --abi ../../IAllowList.abi --bin artifacts/IAllowList.bin --out gen_allowlist_binding.go
//go:generate go run github.com/ava-labs/libevm/cmd/abigen --pkg bindings --type AllowListTest --abi artifacts/AllowListTest.abi --bin artifacts/AllowListTest.bin --out gen_allowlisttest_binding.go
// Step 4: Replace import paths in generated binding to use subnet-evm instead of libevm
// This is necessary because the libevm bindings package is not compatible with the subnet-evm simulated backend, which is used for testing.
Expand Down
4 changes: 0 additions & 4 deletions precompile/allowlist/allowlisttest/test_allowlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,6 @@ func AllowListTests(_ testing.TB, module modules.Module) []precompiletest.Precom
res := allowlist.GetAllowListStatus(state, contractAddress, TestNoRoleAddr)
require.Equal(t, allowlist.NoRole, res)

// Check logs are stored in state
logs := state.Logs()
assertSetRoleEvent(t, logs, allowlist.NoRole, TestEnabledAddr, TestManagerAddr, allowlist.EnabledRole)
},
Expand Down Expand Up @@ -637,7 +636,6 @@ func AllowListTests(_ testing.TB, module modules.Module) []precompiletest.Precom
ReadOnly: false,
ExpectedRes: []byte{},
AfterHook: func(t testing.TB, stateDB *extstate.StateDB) {
// Check no logs are stored in state
logs := stateDB.Logs()
require.Empty(t, logs)
},
Expand All @@ -660,7 +658,6 @@ func AllowListTests(_ testing.TB, module modules.Module) []precompiletest.Precom
ReadOnly: false,
ExpectedRes: []byte{},
AfterHook: func(t testing.TB, stateDB *extstate.StateDB) {
// Check no logs are stored in state
logs := stateDB.Logs()
require.Empty(t, logs)
},
Expand All @@ -683,7 +680,6 @@ func AllowListTests(_ testing.TB, module modules.Module) []precompiletest.Precom
ReadOnly: false,
ExpectedRes: []byte{},
AfterHook: func(t testing.TB, stateDB *extstate.StateDB) {
// Check no logs are stored in state
logs := stateDB.Logs()
require.Empty(t, logs)
},
Expand Down
3 changes: 0 additions & 3 deletions precompile/allowlist/allowlisttest/test_allowlist_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ func RunAllowListEventTests(
{
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)
Expand Down Expand Up @@ -133,7 +132,6 @@ func RunAllowListEventTests(
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
Expand All @@ -143,7 +141,6 @@ func RunAllowListEventTests(
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())
})
Expand Down
83 changes: 45 additions & 38 deletions precompile/contracts/feemanager/IFeeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,52 @@ pragma solidity ^0.8.24;
import "precompile/allowlist/IAllowList.sol";

interface IFeeManager is IAllowList {
struct FeeConfig {
uint256 gasLimit;
uint256 targetBlockRate;
uint256 minBaseFee;
uint256 targetGas;
uint256 baseFeeChangeDenominator;
uint256 minBlockGasCost;
uint256 maxBlockGasCost;
uint256 blockGasCostStep;
}
event FeeConfigChanged(address indexed sender, FeeConfig oldFeeConfig, FeeConfig newFeeConfig);
struct FeeConfig {
uint256 gasLimit;
uint256 targetBlockRate;
uint256 minBaseFee;
uint256 targetGas;
uint256 baseFeeChangeDenominator;
uint256 minBlockGasCost;
uint256 maxBlockGasCost;
uint256 blockGasCostStep;
}
event FeeConfigChanged(
address indexed sender,
FeeConfig oldFeeConfig,
FeeConfig newFeeConfig
);

// Set fee config fields to contract storage
function setFeeConfig(
uint256 gasLimit,
uint256 targetBlockRate,
uint256 minBaseFee,
uint256 targetGas,
uint256 baseFeeChangeDenominator,
uint256 minBlockGasCost,
uint256 maxBlockGasCost,
uint256 blockGasCostStep
) external;
// Set fee config fields to contract storage
function setFeeConfig(
uint256 gasLimit,
uint256 targetBlockRate,
uint256 minBaseFee,
uint256 targetGas,
uint256 baseFeeChangeDenominator,
uint256 minBlockGasCost,
uint256 maxBlockGasCost,
uint256 blockGasCostStep
) external;

// Get fee config from the contract storage
function getFeeConfig()
external
view
returns (
uint256 gasLimit,
uint256 targetBlockRate,
uint256 minBaseFee,
uint256 targetGas,
uint256 baseFeeChangeDenominator,
uint256 minBlockGasCost,
uint256 maxBlockGasCost,
uint256 blockGasCostStep
);
// Get fee config from the contract storage
function getFeeConfig()
external
view
returns (
uint256 gasLimit,
uint256 targetBlockRate,
uint256 minBaseFee,
uint256 targetGas,
uint256 baseFeeChangeDenominator,
uint256 minBlockGasCost,
uint256 maxBlockGasCost,
uint256 blockGasCostStep
);

// Get the last block number changed the fee config from the contract storage
function getFeeConfigLastChangedAt() external view returns (uint256 blockNumber);
// Get the last block number changed the fee config from the contract storage
function getFeeConfigLastChangedAt()
external
view
returns (uint256 blockNumber);
}
2 changes: 1 addition & 1 deletion precompile/contracts/feemanager/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var (
ErrUnpackOutput = errors.New("failed to unpack output")

// IFeeManagerRawABI contains the raw ABI of FeeManager contract.
//go:embed contract.abi
//go:embed IFeeManager.abi
FeeManagerRawABI string

FeeManagerABI = contract.ParseABI(FeeManagerRawABI)
Expand Down
Loading