Skip to main content

Fee Structure & Economics

Nexis Appchain implements a sophisticated fee structure based on EIP-1559, optimized for low-cost AI agent operations while maintaining economic sustainability and security.

Overview

Base Fee

1 gwei minimum (adjustable)

EIP-1559

Dynamic fee market with priority tips

Multi-Vault

3-vault system for fee distribution

EIP-1559 Implementation

Fee Components

Every transaction on Nexis has two fee components:
Total Fee = (Base Fee + Priority Fee) × Gas Used
1. Base Fee
  • Minimum: 1 gwei
  • Dynamic: Adjusts based on block utilization
  • Target: 50% block capacity (15M gas)
  • Burned/Redistributed: 70% of base fee
2. Priority Fee (Tip)
  • Minimum: 0 gwei
  • User-defined: Higher tips = faster inclusion
  • Recipient: 100% to sequencer
  • Typical: 0-2 gwei for normal priority

Base Fee Adjustment

Base Fee Calculation
contract FeeManager {
    uint256 public constant BASE_FEE_MIN = 1 gwei;
    uint256 public constant BASE_FEE_MAX = 100 gwei;
    uint256 public constant TARGET_GAS_PER_BLOCK = 15_000_000;
    uint256 public constant MAX_GAS_PER_BLOCK = 30_000_000;

    uint256 public baseFee = 1 gwei;

    /// @notice Update base fee based on previous block usage
    /// @param gasUsed Gas used in previous block
    function updateBaseFee(uint256 gasUsed) external {
        if (gasUsed > TARGET_GAS_PER_BLOCK) {
            // Increase base fee by 12.5% per block above target
            uint256 increase = (baseFee * (gasUsed - TARGET_GAS_PER_BLOCK)) /
                              TARGET_GAS_PER_BLOCK / 8;
            baseFee = min(baseFee + increase, BASE_FEE_MAX);
        } else if (gasUsed < TARGET_GAS_PER_BLOCK) {
            // Decrease base fee by 12.5% per block below target
            uint256 decrease = (baseFee * (TARGET_GAS_PER_BLOCK - gasUsed)) /
                              TARGET_GAS_PER_BLOCK / 8;
            baseFee = max(baseFee - decrease, BASE_FEE_MIN);
        }
    }

    /// @notice Calculate transaction cost
    function calculateTxCost(
        uint256 gasUsed,
        uint256 priorityFee
    ) public view returns (uint256) {
        return gasUsed * (baseFee + priorityFee);
    }
}

Fee Estimation

const provider = new ethers.JsonRpcProvider('https://rpc.nex-t1.ai');

// Get current fee data
const feeData = await provider.getFeeData();
console.log(`Base Fee: ${ethers.formatUnits(feeData.gasPrice, 'gwei')} gwei`);
console.log(`Max Fee: ${ethers.formatUnits(feeData.maxFeePerGas, 'gwei')} gwei`);
console.log(`Priority Fee: ${ethers.formatUnits(feeData.maxPriorityFeePerGas, 'gwei')} gwei`);

// Estimate transaction cost
const gasEstimate = await provider.estimateGas({
  from: senderAddress,
  to: recipientAddress,
  value: ethers.parseEther("1.0")
});

const baseFee = feeData.gasPrice;
const priorityFee = feeData.maxPriorityFeePerGas || 0n;
const totalCost = gasEstimate * (baseFee + priorityFee);

console.log(`Gas Estimate: ${gasEstimate.toString()}`);
console.log(`Total Cost: ${ethers.formatEther(totalCost)} NZT`);

Fee Vault System

Nexis implements a three-vault system for fee distribution:

1. BaseFeeVault

The BaseFeeVault receives 70% of all transaction fees:
BaseFeeVault Contract
contract BaseFeeVault {
    address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
    address public stakingContract;

    uint256 public constant BURN_PERCENTAGE = 50; // 50%
    uint256 public constant STAKING_PERCENTAGE = 50; // 50%

    uint256 public totalCollected;
    uint256 public totalBurned;
    uint256 public totalDistributed;

    event FeesCollected(uint256 amount);
    event FeesBurned(uint256 amount);
    event FeesDistributed(uint256 amount);

    /// @notice Distribute accumulated fees
    function distribute() external {
        uint256 balance = address(this).balance;
        require(balance > 0, "No fees to distribute");

        uint256 burnAmount = (balance * BURN_PERCENTAGE) / 100;
        uint256 stakingAmount = balance - burnAmount;

        // Burn 50%
        (bool burnSuccess,) = BURN_ADDRESS.call{value: burnAmount}("");
        require(burnSuccess, "Burn failed");
        totalBurned += burnAmount;

        // Send 50% to staking contract
        (bool stakingSuccess,) = stakingContract.call{value: stakingAmount}("");
        require(stakingSuccess, "Staking transfer failed");
        totalDistributed += stakingAmount;

        emit FeesBurned(burnAmount);
        emit FeesDistributed(stakingAmount);
    }

    /// @notice Receive fees from block production
    receive() external payable {
        totalCollected += msg.value;
        emit FeesCollected(msg.value);
    }
}
Distribution Breakdown:
  • 50% Burned: Permanently removed from circulation → deflationary pressure
  • 50% Staking Rewards: Distributed to NZT stakers → yield generation

2. SequencerFeeVault

Receives 20% of fees to fund sequencer operations:
SequencerFeeVault Contract
contract SequencerFeeVault {
    address public sequencerOperator;
    uint256 public withdrawalThreshold = 10 ether; // 10 NZT

    event SequencerWithdrawal(address indexed operator, uint256 amount);

    /// @notice Withdraw fees for sequencer operations
    function withdraw() external {
        require(msg.sender == sequencerOperator, "Not sequencer");
        require(address(this).balance >= withdrawalThreshold, "Below threshold");

        uint256 amount = address(this).balance;
        (bool success,) = sequencerOperator.call{value: amount}("");
        require(success, "Withdrawal failed");

        emit SequencerWithdrawal(sequencerOperator, amount);
    }

    receive() external payable {}
}
Usage:
  • Infrastructure costs (servers, bandwidth)
  • Monitoring and maintenance
  • Emergency reserves
  • Future decentralized sequencer rewards

3. L1FeeVault

Receives 10% to cover Base L2 data availability costs:
L1FeeVault Contract
contract L1FeeVault {
    address public batcherAddress;

    event L1CostsCovered(uint256 amount, bytes32 batchHash);

    /// @notice Pay for L2 batch submission
    function coverL1Costs(bytes32 batchHash, uint256 amount) external {
        require(msg.sender == batcherAddress, "Not batcher");
        require(address(this).balance >= amount, "Insufficient balance");

        (bool success,) = batcherAddress.call{value: amount}("");
        require(success, "Payment failed");

        emit L1CostsCovered(amount, batchHash);
    }

    receive() external payable {}
}
Purpose:
  • Pay for batch submission to Base L2
  • Cover calldata costs on Base
  • Buffer for gas price spikes
  • Ensure data availability

L1 Data Availability Costs

Nexis batches transactions and posts them to Base L2 for data availability. This incurs costs:

Cost Calculation

function calculateL1Cost(
  batchSize,        // Bytes in batch
  baseL2GasPrice,   // Base L2 gas price (wei)
  calldataGas       // 16 gas per non-zero byte
) {
  // L1 gas = calldata cost
  const l1Gas = batchSize * calldataGas;

  // L1 cost in Base L2 native token (ETH)
  const l1CostETH = l1Gas * baseL2GasPrice;

  // Convert to NZT equivalent
  const ethToNztRate = 2000; // 1 ETH = 2000 NZT
  const l1CostNZT = l1CostETH * ethToNztRate;

  return {
    l1Gas,
    l1CostETH,
    l1CostNZT,
    costPerTx: l1CostNZT / (batchSize / 200) // Assume 200 bytes per tx
  };
}

// Example: 100 KB batch at 1 gwei Base L2 gas price
const result = calculateL1Cost(
  100_000,   // 100 KB
  1e9,       // 1 gwei
  16         // Calldata gas per byte
);

console.log(`L1 Gas: ${result.l1Gas.toLocaleString()}`);
console.log(`L1 Cost: ${result.l1CostETH} ETH`);
console.log(`L1 Cost: ${result.l1CostNZT.toLocaleString()} NZT`);
console.log(`Cost per tx: ${result.costPerTx.toFixed(6)} NZT`);

// Output:
// L1 Gas: 1,600,000
// L1 Cost: 0.0016 ETH
// L1 Cost: 3,200 NZT
// Cost per tx: 6.4 NZT

Batch Optimization

# Optimize batch size for cost efficiency
def optimize_batch(tx_count, avg_tx_size, base_l2_gas_price):
    """
    Calculate optimal batch size considering:
    - Calldata costs on Base L2
    - Batch submission overhead
    - Transaction inclusion delay
    """
    batch_size = tx_count * avg_tx_size
    calldata_cost = batch_size * 16 * base_l2_gas_price

    # Add overhead for batch header, proof, etc.
    overhead = 500 * base_l2_gas_price

    total_cost = calldata_cost + overhead
    cost_per_tx = total_cost / tx_count

    return {
        'batch_size_bytes': batch_size,
        'total_l1_cost': total_cost,
        'cost_per_tx': cost_per_tx,
        'efficiency': tx_count / (batch_size / 1000)  # txs per KB
    }

# Example: Optimize for 1000 transactions
result = optimize_batch(
    tx_count=1000,
    avg_tx_size=200,
    base_l2_gas_price=1e9  # 1 gwei
)

print(f"Batch size: {result['batch_size_bytes']:,} bytes")
print(f"Total L1 cost: {result['total_l1_cost']:.6f} ETH")
print(f"Cost per tx: {result['cost_per_tx']:.9f} ETH")
print(f"Efficiency: {result['efficiency']:.2f} txs/KB")

Gas Costs by Operation

Standard Operations

OperationGas CostAt 1 gweiAt 10 gweiUSD (@ $2000/ETH)
ETH Transfer21,0000.000021 NZT0.00021 NZT$0.000042
ERC-20 Transfer65,0000.000065 NZT0.00065 NZT$0.00013
ERC-721 Mint100,0000.0001 NZT0.001 NZT$0.0002
Uniswap Swap150,0000.00015 NZT0.0015 NZT$0.0003

Nexis-Specific Operations

OperationGas CostAt 1 gweiAt 10 gweiUSD (@ $2000/ETH)
Register Agent250,0000.00025 NZT0.0025 NZT$0.0005
Stake Tokens120,0000.00012 NZT0.0012 NZT$0.00024
Create Task180,0000.00018 NZT0.0018 NZT$0.00036
Claim Task90,0000.00009 NZT0.0009 NZT$0.00018
Submit Proof150,0000.00015 NZT0.0015 NZT$0.0003
Attest Proof80,0000.00008 NZT0.0008 NZT$0.00016
Delegate Stake100,0000.0001 NZT0.001 NZT$0.0002
Unstake Request95,0000.000095 NZT0.00095 NZT$0.00019

Gas Cost Calculator

class GasCostCalculator {
  constructor(baseFee, priorityFee, nztToUSD) {
    this.baseFee = baseFee;        // in gwei
    this.priorityFee = priorityFee; // in gwei
    this.nztToUSD = nztToUSD;      // NZT price in USD
  }

  calculateCost(gasUsed) {
    const totalGwei = gasUsed * (this.baseFee + this.priorityFee);
    const totalNZT = totalGwei / 1e9;
    const totalUSD = totalNZT * this.nztToUSD;

    return {
      gas: gasUsed,
      gwei: totalGwei,
      nzt: totalNZT,
      usd: totalUSD
    };
  }

  compareOperations(operations) {
    return operations.map(op => ({
      operation: op.name,
      ...this.calculateCost(op.gas)
    }));
  }
}

// Example usage
const calculator = new GasCostCalculator(
  1,     // 1 gwei base fee
  0.5,   // 0.5 gwei priority fee
  0.05   // $0.05 per NZT
);

const operations = [
  { name: 'Register Agent', gas: 250_000 },
  { name: 'Submit Proof', gas: 150_000 },
  { name: 'Stake Tokens', gas: 120_000 }
];

const costs = calculator.compareOperations(operations);
console.table(costs);

// Output:
// ┌─────────────────────┬──────────┬──────────┬──────────┬─────────┐
// │     operation       │   gas    │   gwei   │   nzt    │   usd   │
// ├─────────────────────┼──────────┼──────────┼──────────┼─────────┤
// │  Register Agent     │  250000  │  375000  │ 0.000375 │ 0.00002 │
// │  Submit Proof       │  150000  │  225000  │ 0.000225 │ 0.00001 │
// │  Stake Tokens       │  120000  │  180000  │ 0.000180 │ 0.00001 │
// └─────────────────────┴──────────┴──────────┴──────────┴─────────┘

Cost Comparison with Other Chains

Transaction Cost Comparison

ChainBlock TimeBase FeeETH Transfer CostSwap CostRelative Cost
Nexis L32s1 gwei$0.000042$0.00031x
Base L22s0.05 gwei$0.000002$0.0000150.07x
Optimism2s0.08 gwei$0.000003$0.0000240.1x
Arbitrum0.25s0.1 gwei$0.000004$0.000030.13x
Polygon PoS2s100 gwei$0.0042$0.03100x
Ethereum L112s30 gwei$1.26$930,000x
Why higher than Base L2? Nexis is an L3 that batches to Base L2, adding one layer of overhead. However, Nexis optimizes for AI agent workloads with custom contracts and is still 70x cheaper than Polygon and 30,000x cheaper than Ethereum L1.

AI Agent Operation Costs

Comparing Nexis-specific operations across chains:
OperationNexis L3Base L2Ethereum L1Nexis Advantage
Register Agent$0.0005N/AN/ANative
Submit Proof$0.0003$0.000015$920x cheaper than Base
Stake 1000 NZT$0.00024$0.000012$7.230,000x cheaper than L1
Daily Agent Ops~$0.05~$0.0025~$1,500Optimized for AI

Monthly Cost Estimates

For a typical AI agent running on Nexis:
function estimateMonthlyCost(
  dailyTaskClaims,
  dailyProofSubmissions,
  dailyStakingOps,
  avgGasPrice
) {
  const gasCosts = {
    claimTask: 90_000,
    submitProof: 150_000,
    stakingOp: 120_000
  };

  const dailyCost =
    (dailyTaskClaims * gasCosts.claimTask +
     dailyProofSubmissions * gasCosts.submitProof +
     dailyStakingOps * gasCosts.stakingOp) *
    avgGasPrice / 1e9; // Convert to NZT

  const monthlyCost = dailyCost * 30;

  return {
    dailyGas: dailyCost / avgGasPrice * 1e9,
    dailyCostNZT: dailyCost,
    monthlyCostNZT: monthlyCost,
    monthlyCostUSD: monthlyCost * 0.05 // Assume $0.05 per NZT
  };
}

// Example: Active agent
const activeCost = estimateMonthlyCost(
  10,    // 10 task claims per day
  10,    // 10 proof submissions per day
  2,     // 2 staking operations per day
  1e-9   // 1 gwei
);

console.log(`Daily gas: ${activeCost.dailyGas.toLocaleString()}`);
console.log(`Monthly cost: ${activeCost.monthlyCostNZT.toFixed(6)} NZT`);
console.log(`Monthly cost: $${activeCost.monthlyCostUSD.toFixed(4)}`);

// Output:
// Daily gas: 1,140,000
// Monthly cost: 0.034200 NZT
// Monthly cost: $0.0017

// Compare to Ethereum L1
const l1MonthlyCost = activeCost.monthlyCostUSD * 30000;
console.log(`Same operations on L1: $${l1MonthlyCost.toFixed(2)}`);
// Output: Same operations on L1: $51.00

Fee Revenue & Distribution

Revenue Projections

Based on network activity:
ScenarioDaily TxsAvg GasDaily Fees (NZT)Annual Fees (NZT)Annual Fees (USD @ $0.05)
Launch10,000100k1,000365,000$18,250
Growth100,000100k10,0003,650,000$182,500
Mature1,000,000100k100,00036,500,000$1,825,000
High Usage10,000,000100k1,000,000365,000,000$18,250,000

Distribution Breakdown

For mature network (1M daily transactions):
const dailyFees = 100_000; // NZT

const distribution = {
  baseFee: dailyFees * 0.70,      // 70,000 NZT
  sequencerFee: dailyFees * 0.20, // 20,000 NZT
  l1Fee: dailyFees * 0.10         // 10,000 NZT
};

const baseFeeDistribution = {
  burned: distribution.baseFee * 0.50,  // 35,000 NZT
  stakers: distribution.baseFee * 0.50  // 35,000 NZT
};

console.log('Daily Fee Distribution:');
console.log(`Total Fees: ${dailyFees.toLocaleString()} NZT`);
console.log(`\nBase Fee (70%): ${distribution.baseFee.toLocaleString()} NZT`);
console.log(`  - Burned: ${baseFeeDistribution.burned.toLocaleString()} NZT`);
console.log(`  - Stakers: ${baseFeeDistribution.stakers.toLocaleString()} NZT`);
console.log(`\nSequencer (20%): ${distribution.sequencerFee.toLocaleString()} NZT`);
console.log(`L1 Costs (10%): ${distribution.l1Fee.toLocaleString()} NZT`);

// Annual impact
const annualBurn = baseFeeDistribution.burned * 365;
const annualStaking = baseFeeDistribution.stakers * 365;

console.log(`\nAnnual Burn: ${annualBurn.toLocaleString()} NZT (1.28% of supply)`);
console.log(`Annual Staking: ${annualStaking.toLocaleString()} NZT (1.28% of supply)`);

Fee Optimization Strategies

For Users

Unless urgent, use 0 gwei priority fee. 2-second blocks mean fast inclusion even without tips.
Combine multiple operations (stake + claim task) into one transaction to save on base transaction costs.
Use fee estimation APIs to transact when base fee is at 1 gwei minimum (typically during low-usage periods).
Use efficient contract patterns, minimize storage writes, and leverage view functions where possible.

For Developers

Gas Optimization Patterns
contract OptimizedAgent {
    // ❌ Bad: Multiple storage writes
    function registerBad(string memory name, string memory metadata) external {
        agents[msg.sender].name = name;
        agents[msg.sender].metadata = metadata;
        agents[msg.sender].timestamp = block.timestamp;
    }

    // ✅ Good: Single storage write
    function registerOptimized(string memory name, string memory metadata) external {
        agents[msg.sender] = Agent({
            name: name,
            metadata: metadata,
            timestamp: block.timestamp
        });
    }

    // ✅ Even better: Pack data to reduce storage slots
    struct PackedAgent {
        string name;
        string metadata;
        uint64 timestamp;  // Packed with other fields
        uint64 reputation;
        uint64 stakeAmount;
        uint64 taskCount;
    }
}

Governance Controls

Fee parameters are governance-controlled:
contract FeeGovernance {
    // Adjustable parameters
    uint256 public minBaseFee = 1 gwei;
    uint256 public maxBaseFee = 100 gwei;
    uint256 public baseFeePercentage = 70;    // 70%
    uint256 public sequencerPercentage = 20;  // 20%
    uint256 public l1Percentage = 10;         // 10%

    /// @notice Update fee split (governance only)
    function updateFeeSplit(
        uint256 _baseFee,
        uint256 _sequencer,
        uint256 _l1
    ) external onlyGovernance {
        require(_baseFee + _sequencer + _l1 == 100, "Must equal 100%");

        baseFeePercentage = _baseFee;
        sequencerPercentage = _sequencer;
        l1Percentage = _l1;

        emit FeeSplitUpdated(_baseFee, _sequencer, _l1);
    }

    /// @notice Update min/max base fee (governance only)
    function updateBaseFeeRange(
        uint256 _min,
        uint256 _max
    ) external onlyGovernance {
        require(_min < _max, "Invalid range");
        minBaseFee = _min;
        maxBaseFee = _max;

        emit BaseFeeRangeUpdated(_min, _max);
    }
}

Monitoring & Analytics

Real-time Fee Tracking

const provider = new ethers.JsonRpcProvider('https://rpc.nex-t1.ai');

async function trackFees() {
  // Get latest block
  const block = await provider.getBlock('latest');

  // Calculate metrics
  const baseFee = block.baseFeePerGas;
  const gasUsed = block.gasUsed;
  const totalFees = baseFee * gasUsed;

  // Get vault balances
  const baseFeeVault = '0x...';
  const sequencerVault = '0x...';
  const l1Vault = '0x...';

  const vaultBalances = await Promise.all([
    provider.getBalance(baseFeeVault),
    provider.getBalance(sequencerVault),
    provider.getBalance(l1Vault)
  ]);

  return {
    blockNumber: block.number,
    baseFee: ethers.formatUnits(baseFee, 'gwei'),
    gasUsed: gasUsed.toString(),
    totalFees: ethers.formatEther(totalFees),
    vaults: {
      baseFee: ethers.formatEther(vaultBalances[0]),
      sequencer: ethers.formatEther(vaultBalances[1]),
      l1: ethers.formatEther(vaultBalances[2])
    }
  };
}

// Monitor fees every block
provider.on('block', async (blockNumber) => {
  const metrics = await trackFees();
  console.log(`Block ${blockNumber}:`, metrics);
});

Public Dashboard

Track live fee metrics:

Fee Analytics Dashboard

Real-time fee tracking, vault balances, and historical trends

Frequently Asked Questions

Nexis is an L3 built on Base L2, adding one layer of coordination overhead. However, fees are optimized for AI agent operations and are still 30,000x cheaper than Ethereum L1.
Not directly. However, you can use meta-transactions or account abstraction to have a relayer pay NZT fees while you pay in USDC or other tokens.
Burned fees are sent to address 0x000…dEaD and permanently removed from circulation, creating deflationary pressure on NZT supply.
No. 1 gwei is the hardcoded minimum to prevent spam and ensure economic security. Governance can adjust this minimum via proposal.
BaseFeeVault distributes when balance exceeds threshold (typically every 24 hours). Sequencer and L1 vaults distribute as needed for operations.
Sequencer can temporarily subsidize L1 costs. Governance can also adjust fee split to allocate more to L1 vault if data costs spike.

Additional Resources


Cost Efficient AI Infrastructure: Nexis fees are designed to enable economically viable AI agent operations while maintaining network security and sustainability.