Update the 3 DataHaven environments' chain IDs & native token ticker as
follows:
* **Mainnet**
* **Chain ID**: 55930
* **Ticker**: HAVE
* **TestNet**
* **Chain ID**: 55931
* **Ticker**: MOCK
* **Stagenet**
* **Chain ID**: 55932
* **Ticker**: STAGE
The PR includes a storage migration for the Stagenet & Testnet
environments, that are already live, to update the EVM Chain ID stored
in the `pallet-evm-chain-id` pallet.
Note: the token symbol will only be updated with the genesis config
presets or newly generated chain specs. For already live networks, the
existing chain spec must be updated (i.e. the tokenSymbol property
changed) and used by all nodes in the network. This change in the chain
spec will not alter the chain genesis so it safe to do (in the very
early stages of the chain obviously).
---------
Co-authored-by: Claude <noreply@anthropic.com>
(cherry picked from commit a97f0547a9)
Add defensive validation to ensure the Ethereum sovereign account has
sufficient balance before unlocking tokens. This addresses an audit
finding where the lack of explicit balance checking created an
unreliable security control that depended on implicit runtime behavior.
Changes:
- Add InsufficientSovereignBalance error variant for clear error
messaging
- Add explicit balance check in unlock_tokens before transfer
- Update tests across all runtimes (testnet, stagenet, mainnet) to
validate the specific error is returned when sovereign account has
insufficient funds
The explicit check provides better error messages that can propagate
through the Ethereum bridge and makes debugging sovereign account
balance issues easier.
# ✨ Implement Dynamic Fee Adjustment Mechanism
## Overview
Implements a dynamic fee adjustment mechanism, replacing the constant
fee multiplier with an adaptive multiplier that responds to network
congestion, following Moonbeam's pattern.
## Changes
- Replaces `ConstFeeMultiplier` with `TargetedFeeAdjustment` across all
runtime configurations (mainnet, stagenet, testnet)
- Implements an EIP-1559-like slow-adjusting fee mechanism that prevents
DoS attacks by adjusting fees based on block fullness
- **Configurable Parameters**:
- Target block fullness: 35%
- Adjustment variable: 4/1000 (responds in ~1 hour at extreme
congestion)
- Two modes:
- `SlowAdjustingFeeUpdate` for mainnet and testnet.
- `FastAdjustingFeeUpdate` for stagenet.
- Adds tests coverage for different fee scenarios
## Technical Details
The fee adjustment algorithm works as follows:
```
diff = (previous_block_weight - target) / maximum_block_weight
next_multiplier = prev_multiplier * (1 + (v * diff) + ((v * diff)^2 / 2))
assert(next_multiplier > min)
```
**Where:**
- `v` = AdjustmentVariable
- `target` = TargetBlockFullness
- `min` = MinimumMultiplier
`SlowAdjustingFeeUpdate` sets a minimum multiplier of `1x` for a
conservative fee adjustment, while `FastAdjustingFeeUpdate` sets it to
`0.1x`, which is mainly used for dev networks / testing.
## Summary
- rename the FRAME alias for `pallet_evm` from `Evm` to `EVM` across the
mainnet, stagenet, and testnet runtimes
- adjust benchmarks, configuration modules, genesis builders, and
runtime tests to rely on the new alias
- keep precompile genesis setup and proxy/precompile tests aligned with
the updated names
## Context
Frontier’s `StorageOverrideHandler` (see
`fc_storage::StorageQuerier::account_code`) reads contract bytecode from
`pallet_evm::AccountCodes` using the constant `PALLET_EVM = b"EVM"` to
build the storage key:
`twox_128("EVM") ++ twox_128("AccountCodes") ++ …`
Our runtimes exported `pallet_evm` as `Evm`, so substrate stored
bytecode under the *camel-cased* prefix (`twox_128("Evm")`). Every call
that ultimately hits the storage override—including `eth_getCode`,
`eth_call`, and state queries during replay—therefore failed to locate
code for *any* account (deployed contracts and precompiles alike).
Renaming the alias to `EVM` realigns the storage prefix with Frontier’s
expectations so the override layers can pull bytecode correctly.
## Testing
- `cargo check -p datahaven-node`
- `cargo build --release -p datahaven-node`
- `eth_getCode 0x0000000000000000000000000000000000000802` → returns
`0x60006000fd`
## Storage Migration
Renaming a pallet alias changes the storage prefix for all pallet data.
Without migration, existing EVM data (smart contracts, account codes,
storage) would become inaccessible.
**Migration details:**
- **Type**: Multi-Block Migration (MBM)
- **Storage migrated**: `AccountCodes`, `AccountCodesMetadata`,
`AccountStorages`
- **Migration ID**: `datahaven-evm-mbm` (version 0 → 1)
**Testing the migration:**
```bash
# Build runtime with try-runtime
cargo build --release --features try-runtime -p
datahaven-stagenet-runtime
# Test against stagenet
try-runtime \
--runtime
./target/release/wbuild/datahaven-stagenet-runtime/datahaven_stagenet_runtime.wasm
\
on-runtime-upgrade \
--blocktime 6000 \
--checks all \
--disable-spec-version-check \
live --uri wss://dh-validator-0.datahaven-kt.xyz
```
Test results from stagenet:
- ✅ Migration completes in 1 block
- ✅ PoV size: ~5.3 KB
- ✅ Weight consumption: <0.1% of block capacity
- ✅ All 39 keys successfully migrated
## ⚠️ Breaking Changes ⚠️
If you are manually computing storage keys for the EVM pallet (e.g., directly querying chain state), you must update your code to use the new storage prefix:
- Old prefix: twox128("Evm") = 0x8b90cb...
- New prefix: twox128("EVM") = 0x6a5e91...
All EVM-facing interfaces remain unchanged.
## Add proxy call filtering for EVM accounts
This PR implements a `NormalCallFilter` following moonbeam filters.
### Changes
- Added `NormalCallFilter` implementation across all runtime
configurations (mainnet, stagenet, testnet)
- Configured the filter as `BaseCallFilter` in `frame_system::Config`
### Security Improvements
The filter blocks:
- **Proxy calls to EVM accounts** - Prevents proxying to smart contracts
- **Direct EVM pallet calls** - Prevents reentrancy from precompiles
(following Moonbeam's security pattern)
This aligns with best practices from Moonbeam and addresses known
security considerations around EVM/Substrate interaction patterns.
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## Summary
This PR integrates the Substrate Proxy pallet into DataHaven runtimes
(testnet, stagenet, mainnet) with comprehensive test coverage. The proxy
pallet enables account delegation functionality, allowing accounts to
authorize other accounts to execute calls on their behalf with
configurable permissions.
## Changes
### Proxy Pallet Integration
- **Added proxy pallet** to all three DataHaven runtimes (testnet,
stagenet, mainnet)
- **Configured custom ProxyType enum** with DataHaven-specific proxy
types:
- `Any` - Unrestricted proxy access
- `NonTransfer` - All calls except balance transfers
- `Governance` - Governance and utility calls only
- `Staking` - Staking operations (placeholder)
- `CancelProxy` - Proxy announcement cancellation
- `Balances` - Balance transfer operations only
- `IdentityJudgement` - Identity judgement operations
- `SudoOnly` - Privileged sudo operations only
### Runtime Configuration
- **Integrated pallet-proxy** into runtime construction macros
- **Configured proxy deposits** (base + per-proxy fees)
- **Set proxy limits** (maximum proxies per account)
- **Implemented InstanceFilter** for call filtering per proxy type
- **Added proxy pallet to runtime APIs** and metadata
### Comprehensive Test Suite
- `operator/runtime/testnet/tests/proxy.rs` - 24 comprehensive proxy
tests
- `operator/runtime/stagenet/tests/proxy.rs` - 24 comprehensive proxy
tests
- `operator/runtime/mainnet/tests/proxy.rs` - 24 comprehensive proxy
tests
- Updated `lib.rs` files in all three runtimes to include proxy test
modules
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- New Features
- Enable account proxies across mainnet, stagenet, and testnet with
configurable types, delays, and per-type call permissions.
- Support anonymous (pure) proxies, proxy announcements with delays, and
deposit/limit parameters for proxy management.
- Tests
- Add comprehensive integration tests covering proxy lifecycle,
filtering, pure proxies, announcements, batching, chaining, multisig,
identity, and sudo paths.
- Test builder now supports optional sudo setup.
- Chores
- Add benchmarking, weights, and try-runtime support for proxies.
- Update internal package metadata version.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ahmad Kaouk <ahmadkaouk.93@gmail.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
## Overview
This PR implements the **return path** for DataHaven's native token
bridge, enabling tokens that were previously transferred from DataHaven
to Ethereum to flow back to DataHaven.
**Context**: DataHaven native tokens can be transferred to Ethereum
where they exist as wrapped ERC20 tokens. This PR completes the
bidirectional bridge by implementing the mechanism to transfer these
tokens back from Ethereum to DataHaven, effectively "unwrapping" them
and restoring them to their native form.
## Key Changes
- **Added `NativeTokenTransferMessageProcessor`** , a new message
processor specifically designed to handle native token return transfers
from Ethereum, and extended `InboundQueueV2` processor tuple to include
native token transfer handling alongside existing EigenLayer message
processing
## How It Works
### Detailed Flow: Ethereum → DataHaven
#### 1. **Ethereum Initiation**
- **User Transaction**: User calls `v2_sendMessage` on Snowbridge
Gateway contract:
```solidity
v2_sendMessage(
assets: [{
kind: ForeignToken,
assetId: <registered_native_token_id>, // Must match pre-registered
token ID
amount: <transfer_amount>
}],
claimer: <datahaven_recipient_as_h160>, // 20-byte recipient address
(SCALE-encoded)
message: [], // Empty for native transfers
// ... standard Snowbridge fees
)
```
- **Token Burning**: Gateway burns the wrapped ERC20 tokens on Ethereum
(removing them from circulation)
- **Message Encoding**: Gateway encodes transfer details into
standardized Snowbridge message format
- **Event Emission**: `MessageAccepted` event logged on Ethereum for
relayers to pick up
#### 2. **Cross-Chain Delivery Infrastructure**
- **Relayer Network**: Snowbridge relayers monitor Ethereum events and
submit messages to DataHaven
- **Consensus Verification**: DataHaven's `EthereumBeaconClient` pallet
verifies Ethereum beacon chain consensus
- **Cryptographic Proofs**: Messages include Merkle proofs and execution
receipts for tamper-proof verification
- **Direct Processing**: Relayers submit messages via
`InboundQueueV2::submit()` which processes them immediately
#### 3. **DataHaven Message Processing**
**Immediate Processing Flow:**
When a relayer calls `InboundQueueV2::submit()`, the message is
processed immediately using a tuple-based processor system:
```rust
type MessageProcessor = (
EigenLayerMessageProcessor<Runtime>, // Handles validator operations
NativeTokenTransferMessageProcessor<Runtime>, // Handles native token returns
);
```
**Processing Steps:**
1. **Message Verification**: Cryptographic verification and nonce
checking (prevents replay attacks)
2. **Processor Selection**: Evaluation of processors (First processor
returning `true` handles the message):
- `EigenLayerMessageProcessor::can_process_message()` - returns `false`
for token transfers
- `NativeTokenTransferMessageProcessor::can_process_message()` -
validates:
- Native token is registered via `SnowbridgeSystemV2::register_token()`
(`T::NativeTokenId::get().is_some()`)
- All assets are `ForeignTokenERC20` with matching native token ID
- Assets array is not empty
**Token Unlocking Process:**
1. **Recipient Extraction**: Decodes H160 address from `claimer` field →
converts to DataHaven AccountId (must contain valid SCALE-encoded H160
address)
2. **Sovereign Account Transfer**: Moves tokens from Ethereum sovereign
account to recipient (requires sufficient balance from previous outbound
transfers)
3. **Event Emission**: `TokensUnlocked` event confirms successful
transfer completion
---------
Co-authored-by: Tobi Demeco <50408393+TDemeco@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
This PR integrates the Substrate FRAME Treasury pallet across all three
DataHaven runtime environments (`testnet`, `mainnet`, `stagenet`) with a
custom fee allocation mechanism and comprehensive test coverage.
### Key Changes
#### Treasury Pallet Integration:
- Added Treasury pallet to all three runtimes (testnet, mainnet,
stagenet) with 20% fee allocation and 80% burn mechanism.
- Implemented dynamic fee proportion control via
`FeesTreasuryProportion` runtime parameter.
- Integrated treasury with custom fee handlers:
`DealWithEthereumBaseFees`, `DealWithEthereumPriorityFees`, and
`DealWithSubstrateFeesAndTip`.
#### Comprehensive Testing Infrastructure:
- Created robust test architecture with session management and validator
setup across all runtimes
- Added block author management utilities for treasury testing requiring
pallet_authorship integration
- Implemented 15 total tests (5 tests × 3 runtimes) covering:
- EVM transaction fee allocation with/without priority fees
- Substrate fee and tip handling validation
- Treasury spending functionality via sudo
- Complete fee flow verification with actual network base fee
calculations
#### Technnical Implementation
Fee Allocation Logic:
- Base fees: 20% to treasury, 80% burned
- Priority fees: 100% to block author
- Substrate tips: 100% to block author
The implementation is based on
https://github.com/moonbeam-foundation/moonbeam/pull/3120 in
[Moonbeam](https://github.com/moonbeam-foundation/moonbeam), and
assisted by Claude Code.
### Summary
- Implement native token transfers from DataHaven to Ethereum using
Snowbridge infrastructure
- Add comprehensive datahaven-native-transfer pallet with lock-and-mint
mechanism for cross-chain token representation
### Key Features
**New Pallet: datahaven-native-transfer**
- Cross-chain transfers: Transfer DataHaven native tokens to Ethereum
addresses via `transfer_to_ethereum extrinsic`
- Token locking mechanism: Secure token storage in deterministic
Ethereum sovereign account during transfers
- Fee management: Required fees for all transfers to compensate relayers
and prevent spam
- Emergency controls: Pause/unpause functionality
- Token registration: Integration with Snowbridge's token registration
for native token identification
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced the DataHaven Native Transfer pallet enabling secure
cross-chain transfers of DataHaven native tokens to and from Ethereum
via Snowbridge.
- Added token locking on DataHaven, minting on Ethereum, and mandatory
fee collection to cover gas costs and incentivize relayers.
- Implemented pause and unpause controls for emergency management of
token transfers.
- **Configuration**
- Integrated the new pallet into mainnet, stagenet, and testnet runtimes
with updated network, account, and treasury settings.
- Added Ethereum sovereign account constants and native token ID support
for optimized cross-chain operations.
- **Documentation**
- Added comprehensive README and inline documentation detailing pallet
features, extrinsics, events, errors, and security considerations.
- **Tests**
- Added extensive unit and integration tests covering token transfers,
native token registration, fee handling, pause functionality, and event
validation across all supported networks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>