> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# DVN Contract Reference

> Comprehensive technical documentation for DVN contracts, including interfaces, methods, events, errors, and data structures for LayerZero V2.

This page provides comprehensive technical documentation for DVN (Decentralized Verifier Network) contracts, including interfaces, methods, events, errors, and data structures.

## Core Interface

All DVNs must implement the `ILayerZeroDVN` interface to integrate with LayerZero's Message Libraries.

### ILayerZeroDVN

```solidity wrap theme={null}
interface ILayerZeroDVN {
    struct AssignJobParam {
        uint32 dstEid;          // Destination endpoint ID
        bytes packetHeader;     // Packet header containing routing info
        bytes32 payloadHash;    // Hash of the message payload
        uint64 confirmations;   // Required block confirmations
        address sender;         // OApp sender address
    }

    /// @notice Assigns a verification job to the DVN
    /// @param _param Job parameters including destination and payload hash
    /// @param _options DVN-specific options
    /// @return fee The fee charged for this verification job
    function assignJob(AssignJobParam calldata _param, bytes calldata _options)
        external payable returns (uint256 fee);

    /// @notice Returns the fee for verifying a message
    /// @param _dstEid Destination endpoint ID
    /// @param _confirmations Required block confirmations
    /// @param _sender OApp sender address
    /// @param _options DVN-specific options
    /// @return fee The fee in native tokens
    function getFee(
        uint32 _dstEid,
        uint64 _confirmations,
        address _sender,
        bytes calldata _options
    ) external view returns (uint256 fee);
}
```

***

## DVN Contract Methods

The LayerZero DVN contract extends the base Worker contract with multisig capabilities. Below are the key methods organized by access control.

### Public / View Methods

#### `getFee`

Returns the fee for verifying a message to a specific destination.

```solidity wrap theme={null}
function getFee(
    uint32 _dstEid,
    uint64 _confirmations,
    address _sender,
    bytes calldata _options
) external view returns (uint256 fee)
```

| Parameter        | Type      | Description                          |
| ---------------- | --------- | ------------------------------------ |
| `_dstEid`        | `uint32`  | Destination endpoint ID              |
| `_confirmations` | `uint64`  | Required block confirmations         |
| `_sender`        | `address` | OApp sender address (for ACL checks) |
| `_options`       | `bytes`   | DVN-specific options                 |

**Returns:** Fee amount in native tokens.

<Note>
  This function will revert if the sender is on the denylist or not on the allowlist (when allowlist is enabled).
</Note>

***

#### `hashCallData`

Generates a hash of execution parameters for signature verification.

```solidity wrap theme={null}
function hashCallData(
    uint32 _vid,
    address _target,
    bytes calldata _callData,
    uint256 _expiration
) public pure returns (bytes32)
```

| Parameter     | Type      | Description                |
| ------------- | --------- | -------------------------- |
| `_vid`        | `uint32`  | DVN instance identifier    |
| `_target`     | `address` | Target contract address    |
| `_callData`   | `bytes`   | Encoded function call data |
| `_expiration` | `uint256` | Expiration timestamp       |

**Returns:** Keccak256 hash of the packed parameters.

***

### OnlyMessageLib Methods

These methods can only be called by authorized Message Libraries.

#### `assignJob` (ULN302)

Assigns a verification job for ULN302 messages.

```solidity wrap theme={null}
function assignJob(
    AssignJobParam calldata _param,
    bytes calldata _options
) external payable onlyRole(MESSAGE_LIB_ROLE) returns (uint256 totalFee)
```

| Parameter  | Type             | Description           |
| ---------- | ---------------- | --------------------- |
| `_param`   | `AssignJobParam` | Job parameters struct |
| `_options` | `bytes`          | DVN-specific options  |

**Emits:** None directly (fee calculation delegated to DVNFeeLib).

***

#### `assignJob` (ULNv2 Legacy)

Assigns a verification job for legacy ULNv2 messages.

```solidity wrap theme={null}
function assignJob(
    uint16 _dstEid,
    uint16 _outboundProofType,
    uint64 _confirmations,
    address _sender
) external onlyRole(MESSAGE_LIB_ROLE) returns (uint256 totalFee)
```

**Emits:** `VerifierFeePaid(uint256 fee)`

***

#### `assignJob` (Read/CmdLib)

Assigns a verification job for lzRead commands.

```solidity wrap theme={null}
function assignJob(
    address _sender,
    bytes calldata _packetHeader,
    bytes calldata _cmd,
    bytes calldata _options
) external payable onlyRole(MESSAGE_LIB_ROLE) returns (uint256 fee)
```

***

### OnlyAdmin Methods

These methods require the `ADMIN_ROLE`.

#### `setDstConfig`

Configures fee parameters for destination chains.

```solidity wrap theme={null}
function setDstConfig(DstConfigParam[] calldata _params) external onlyRole(ADMIN_ROLE)
```

| Parameter | Type               | Description                         |
| --------- | ------------------ | ----------------------------------- |
| `_params` | `DstConfigParam[]` | Array of destination configurations |

**Emits:** `SetDstConfig(DstConfigParam[] params)`

***

#### `execute`

Executes a batch of signed instructions. This is the primary method for submitting verifications.

```solidity wrap theme={null}
function execute(ExecuteParam[] calldata _params) external onlyRole(ADMIN_ROLE)
```

| Parameter | Type             | Description                          |
| --------- | ---------------- | ------------------------------------ |
| `_params` | `ExecuteParam[]` | Array of signed execution parameters |

**Behavior:**

* Skips instructions with invalid VID
* Skips expired instructions
* Validates signatures against quorum
* Prevents replay attacks via hash tracking
* Emits events for failures but continues processing

**Emits:**

* `VerifySignaturesFailed(uint256 idx)` - if signature validation fails
* `ExecuteFailed(uint256 index, bytes data)` - if execution fails
* `HashAlreadyUsed(ExecuteParam param, bytes32 hash)` - if instruction was already executed

***

#### `withdrawFeeFromUlnV2`

Withdraws accumulated fees from ULNv2 Message Library.

```solidity wrap theme={null}
function withdrawFeeFromUlnV2(
    address _lib,
    address payable _to,
    uint256 _amount
) external onlyRole(ADMIN_ROLE)
```

| Parameter | Type              | Description                   |
| --------- | ----------------- | ----------------------------- |
| `_lib`    | `address`         | ULNv2 Message Library address |
| `_to`     | `address payable` | Recipient address             |
| `_amount` | `uint256`         | Amount to withdraw            |

***

### OnlySelf Methods

These methods can only be called by the contract itself (via signed execute).

#### `setSigner`

Adds or removes a signer from the multisig.

```solidity wrap theme={null}
function setSigner(address _signer, bool _active) external onlySelf
```

| Parameter | Type      | Description                      |
| --------- | --------- | -------------------------------- |
| `_signer` | `address` | Signer address                   |
| `_active` | `bool`    | `true` to add, `false` to remove |

**Function Signature:** `0x31cb6105`

***

#### `setQuorum`

Sets the required number of signatures for multisig operations.

```solidity wrap theme={null}
function setQuorum(uint64 _quorum) external onlySelf
```

| Parameter | Type     | Description          |
| --------- | -------- | -------------------- |
| `_quorum` | `uint64` | New quorum threshold |

**Function Signature:** `0x8585c945`

***

### Quorum Methods

#### `quorumChangeAdmin`

Allows the signer quorum to change the admin role without going through the standard execute flow.

```solidity wrap theme={null}
function quorumChangeAdmin(ExecuteParam calldata _param) external
```

| Parameter | Type           | Description                                                   |
| --------- | -------------- | ------------------------------------------------------------- |
| `_param`  | `ExecuteParam` | Signed instruction with new admin address encoded in callData |

**Usage:** The `callData` field should contain `abi.encode(newAdminAddress)`.

<Tip>
  This function ensures signers maintain ultimate control over the DVN. Even if the admin role is delegated to a service like Essence, signers can immediately reassign it.
</Tip>

***

## Events

### Core Events

| Event                    | Signature                                           | Description                                                                 |
| ------------------------ | --------------------------------------------------- | --------------------------------------------------------------------------- |
| `VerifySignaturesFailed` | `VerifySignaturesFailed(uint256 idx)`               | Signature verification failed at the specified index during batch execution |
| `ExecuteFailed`          | `ExecuteFailed(uint256 index, bytes data)`          | Execution failed at the specified index with return data                    |
| `HashAlreadyUsed`        | `HashAlreadyUsed(ExecuteParam param, bytes32 hash)` | Attempted replay of an already-executed instruction                         |
| `VerifierFeePaid`        | `VerifierFeePaid(uint256 fee)`                      | Fee paid for ULNv2 verification job                                         |
| `SetDstConfig`           | `SetDstConfig(DstConfigParam[] params)`             | Destination configuration updated                                           |

### Inherited Events (from Worker)

| Event                     | Signature                                       | Description                    |
| ------------------------- | ----------------------------------------------- | ------------------------------ |
| `SetWorkerFeeLib`         | `SetWorkerFeeLib(address feeLib)`               | Fee library address updated    |
| `SetPriceFeed`            | `SetPriceFeed(address priceFeed)`               | Price feed address updated     |
| `SetDefaultMultiplierBps` | `SetDefaultMultiplierBps(uint16 multiplierBps)` | Default fee multiplier updated |
| `Withdraw`                | `Withdraw(address to, uint256 amount)`          | Fees withdrawn from worker     |

***

## Errors

### DVN Errors

| Error                    | Signature                                    | Description                                                        |
| ------------------------ | -------------------------------------------- | ------------------------------------------------------------------ |
| `DVN_OnlySelf`           | `DVN_OnlySelf()`                             | Action requires the contract to call itself (via signed execute)   |
| `DVN_InvalidRole`        | `DVN_InvalidRole(bytes32 role)`              | Specified role is not valid for the operation                      |
| `DVN_InstructionExpired` | `DVN_InstructionExpired()`                   | The signed instruction has passed its expiration timestamp         |
| `DVN_InvalidTarget`      | `DVN_InvalidTarget(address target)`          | Target address is not valid for this operation                     |
| `DVN_InvalidVid`         | `DVN_InvalidVid(uint32 vid)`                 | VID in instruction does not match this DVN instance                |
| `DVN_InvalidSignatures`  | `DVN_InvalidSignatures()`                    | Signature verification failed (invalid or insufficient signatures) |
| `DVN_DuplicatedHash`     | `DVN_DuplicatedHash(bytes32 executableHash)` | Instruction hash has already been executed (replay prevention)     |

### DVNFeeLib Errors

| Error                       | Signature                                               | Description                                                  |
| --------------------------- | ------------------------------------------------------- | ------------------------------------------------------------ |
| `DVN_EidNotSupported`       | `DVN_EidNotSupported(uint32 eid)`                       | Destination endpoint ID is not configured (gas = 0)          |
| `DVN_INVALID_INPUT_LENGTH`  | `DVN_INVALID_INPUT_LENGTH()`                            | Array lengths do not match in configuration                  |
| `DVN_TimestampOutOfRange`   | `DVN_TimestampOutOfRange(uint32 eid, uint64 timestamp)` | Read request timestamp is outside the valid retention window |
| `DVN_UnsupportedOptionType` | `DVN_UnsupportedOptionType(uint8 optionType)`           | DVN option type is not supported                             |

### Inherited Errors (from Worker)

| Error                   | Signature                 | Description                                 |
| ----------------------- | ------------------------- | ------------------------------------------- |
| `Worker_OnlyMessageLib` | `Worker_OnlyMessageLib()` | Caller is not an authorized Message Library |
| `Worker_NotAllowed`     | `Worker_NotAllowed()`     | Sender is on denylist or not on allowlist   |

***

## Data Structures

### DstConfig

Configuration for a destination chain's fee parameters.

```solidity wrap theme={null}
struct DstConfig {
    uint64 gas;              // Base gas cost for verification
    uint16 multiplierBps;    // Fee multiplier in basis points (10000 = 100%)
    uint128 floorMarginUSD;  // Minimum margin in USD (scaled)
}
```

| Field            | Type      | Description                                                  |
| ---------------- | --------- | ------------------------------------------------------------ |
| `gas`            | `uint64`  | Base gas units required for verification on this destination |
| `multiplierBps`  | `uint16`  | Fee multiplier (0 uses default, 10000 = 1x, 12000 = 1.2x)    |
| `floorMarginUSD` | `uint128` | Minimum fee floor in USD to ensure profitability             |

***

### DstConfigParam

Parameter struct for setting destination configuration.

```solidity wrap theme={null}
struct DstConfigParam {
    uint32 dstEid;           // Destination endpoint ID
    uint64 gas;              // Base gas cost
    uint16 multiplierBps;    // Fee multiplier
    uint128 floorMarginUSD;  // Minimum margin
}
```

***

### ExecuteParam

Parameters for executing a signed instruction.

```solidity wrap theme={null}
struct ExecuteParam {
    uint32 vid;              // DVN instance identifier
    address target;          // Target contract address
    bytes callData;          // Encoded function call
    uint256 expiration;      // Expiration timestamp
    bytes signatures;        // Concatenated signatures
}
```

| Field        | Type      | Description                                       |
| ------------ | --------- | ------------------------------------------------- |
| `vid`        | `uint32`  | Must match this DVN's VID                         |
| `target`     | `address` | Contract to call (often the receive MessageLib)   |
| `callData`   | `bytes`   | ABI-encoded function call (e.g., `verify(...)`)   |
| `expiration` | `uint256` | Unix timestamp after which instruction is invalid |
| `signatures` | `bytes`   | Concatenated 65-byte ECDSA signatures             |

***

### AssignJobParam

Parameters passed when a verification job is assigned.

```solidity wrap theme={null}
struct AssignJobParam {
    uint32 dstEid;           // Destination endpoint ID
    bytes packetHeader;      // Full packet header
    bytes32 payloadHash;     // Hash of message payload
    uint64 confirmations;    // Required block confirmations
    address sender;          // OApp that sent the message
}
```

***

### FeeParams (DVNFeeLib)

Parameters used for fee calculation.

```solidity wrap theme={null}
struct FeeParams {
    address priceFeed;           // Price feed contract address
    uint32 dstEid;               // Destination endpoint ID
    uint64 confirmations;        // Required confirmations
    address sender;              // OApp sender
    uint64 quorum;               // Current quorum setting
    uint16 defaultMultiplierBps; // Default fee multiplier
}
```

***

## Access Control Roles

The DVN contract uses role-based access control inherited from OpenZeppelin's AccessControl.

| Role               | Description                                                 | Controlled By                             |
| ------------------ | ----------------------------------------------------------- | ----------------------------------------- |
| `ADMIN_ROLE`       | Can execute signed instructions, set configs, withdraw fees | Admin (or quorum via `quorumChangeAdmin`) |
| `MESSAGE_LIB_ROLE` | Can call `assignJob` to request verifications               | Self (via signed execute)                 |
| `ALLOWLIST`        | Addresses permitted to use the DVN                          | Self (via signed execute)                 |
| `DENYLIST`         | Addresses blocked from using the DVN                        | Self (via signed execute)                 |

***

## Constructor Parameters

```solidity wrap theme={null}
constructor(
    uint32 _localEidV2,      // Local endpoint V2 ID
    uint32 _vid,             // Unique DVN instance identifier
    address[] memory _messageLibs,  // Initial Message Libraries
    address _priceFeed,      // Price feed contract
    address[] memory _signers,      // Initial multisig signers
    uint64 _quorum,          // Initial quorum requirement
    address[] memory _admins        // Initial admin addresses
)
```

| Parameter      | Description                                                                    |
| -------------- | ------------------------------------------------------------------------------ |
| `_localEidV2`  | The endpoint ID for this chain (used for lzRead)                               |
| `_vid`         | Unique identifier for this DVN instance (typically `eidV1` or `eidV2 % 30000`) |
| `_messageLibs` | Array of Message Library addresses granted `MESSAGE_LIB_ROLE`                  |
| `_priceFeed`   | Contract providing cross-chain gas price estimates                             |
| `_signers`     | Array of addresses that can sign verification instructions                     |
| `_quorum`      | Number of signatures required for execution                                    |
| `_admins`      | Addresses granted `ADMIN_ROLE` for operational management                      |

***

## State Variables

| Variable     | Type                           | Visibility         | Description                        |
| ------------ | ------------------------------ | ------------------ | ---------------------------------- |
| `vid`        | `uint32`                       | `public immutable` | Unique DVN instance identifier     |
| `localEidV2` | `uint32`                       | `public immutable` | Local endpoint V2 ID               |
| `dstConfig`  | `mapping(uint32 => DstConfig)` | `public`           | Fee configuration per destination  |
| `usedHashes` | `mapping(bytes32 => bool)`     | `public`           | Tracks executed instruction hashes |

***

## Related Resources

* [DVN Overview](/v2/workers/off-chain/dvn-overview) - Conceptual introduction to DVNs
* [Build DVNs](/v2/workers/off-chain/build-dvns) - Traditional DVN implementation guide
* [Gasolina Overview](/v2/workers/off-chain/gasolina-overview) - Simplified DVN with gas abstraction
* [Security Stack DVNs](/v2/concepts/modular-security/security-stack-dvns) - OApp security configuration
* [DVN Source Code](https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/packages/layerzero-v2/evm/messagelib/contracts/uln/dvn/DVN.sol) - Reference implementation
