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

# Fee manager

# FeeManager

The `FeeManager` contract (Solidity name `NotareumFeeManager`) centralizes every NOTA-denominated fee the protocol charges, routes collected fees to the treasury, the burn address, and operators, and exposes governance-only setters for the fee parameters. It is the single payment gateway: `NotaRegistry`, `VerificationEngine`, and `SlashingManager` all call through it rather than handling transfers themselves.

## Responsibilities

* Quote fees for each protocol operation.
* Collect fees (either via ERC-20 `transferFrom` or via the attached ETH paid on the origin call when applicable).
* Split collected fees between treasury, burn, and optional validator rewards pool.
* Maintain the fee tables that `RegistryOps`, `VerifyOps`, and `AttestationOps` all query.
* Refund partial fees on expired verification requests.

## Fee categories

| Operation                    | Payer     | Default fee (NOTA) | Notes                   |
| ---------------------------- | --------- | -----------------: | ----------------------- |
| Register resource            | Owner     |                 10 | Per registration        |
| Update resource              | Owner     |                  2 | Per update              |
| Revoke resource              | Owner     |                  0 | Free                    |
| Verify, Basic                | Requester |                100 | 3-validator quorum      |
| Verify, Enhanced             | Requester |                500 | 7-validator quorum      |
| Verify, Institutional        | Requester |              2,500 | 15-validator quorum     |
| Attest (paid by request fee) | Protocol  |                  0 | Validators are paid out |
| Dispute bond, Basic          | Disputant |                200 | Returned on win         |
| Dispute bond, Enhanced       | Disputant |              1,000 | Returned on win         |
| Dispute bond, Institutional  | Disputant |              5,000 | Returned on win         |

Defaults are governance-set on deployment. All numbers above are the proposed launch values in the spec; the contract reads them from storage set at initialization.

## Splits

Every collected fee routes through three buckets:

```
collected = treasuryBps + burnBps + validatorPoolBps (bps, sum = 10000)
```

Default split:

| Destination           |        bps |
| --------------------- | ---------: |
| Treasury              | 4000 (40%) |
| Burn                  | 2000 (20%) |
| Validator reward pool | 4000 (40%) |

The validator pool feeds the attestation reward distribution inside `ValidatorStaking`. The burn share goes to `address(0xdead)` and is permanently removed from circulation. Bps are adjustable via governance.

## Data structures

```solidity theme={"system"}
struct FeeTable {
    uint128 registerFee;
    uint128 updateFee;
    uint128 verifyFeeBasic;
    uint128 verifyFeeEnhanced;
    uint128 verifyFeeInstitutional;
    uint128 disputeBondBasic;
    uint128 disputeBondEnhanced;
    uint128 disputeBondInstitutional;
}

struct Split {
    uint16 treasuryBps;
    uint16 burnBps;
    uint16 validatorPoolBps;
}
```

## Functions

### `quote`

```solidity theme={"system"}
function quote(OpKind op) external view returns (uint256 fee);
```

Returns the NOTA fee for the operation. The `OpKind` enum lists every chargeable action: `Register`, `Update`, `VerifyBasic`, `VerifyEnhanced`, `VerifyInstitutional`, `DisputeBondBasic`, `DisputeBondEnhanced`, `DisputeBondInstitutional`.

### `collect`

```solidity theme={"system"}
function collect(OpKind op, address payer) external returns (uint256 fee);
```

Pulls the fee from `payer` (requires ERC-20 allowance on NOTA) and applies the split. Callable only by the pre-wired protocol contracts (`NotaRegistry`, `VerificationEngine`, `SlashingManager`). Emits `FeeCollected(op, payer, fee, treasuryShare, burnShare, validatorShare)`.

### `refund`

```solidity theme={"system"}
function refund(OpKind op, address payee, uint256 partialAmount) external;
```

Used by `VerificationEngine` when a verification request expires without reaching quorum. Refunds the unused portion of the fee from the validator pool (or directly from the contract balance). Emits `FeeRefunded(op, payee, amount)`.

### Governance setters

```solidity theme={"system"}
function setFeeTable(FeeTable calldata table) external;  // TREASURY_ADMIN
function setSplit(Split calldata split) external;        // TREASURY_ADMIN
function setTreasury(address newTreasury) external;      // TREASURY_ADMIN
function setValidatorPool(address newPool) external;     // TREASURY_ADMIN
```

All setters are delay-gated through [AccessManager](access-manager.md). The `TREASURY_ADMIN` role is held by a timelocked governance executor; the default delay is 14 days.

### `distribute`

```solidity theme={"system"}
function distribute() external;
```

Callable by anyone. Flushes any pending per-bucket balances to their destinations. Used as a gas-optimization path when `collect` accumulates fees without transferring on every call. Emits `FeesDistributed(treasury, burned, validatorPool)`.

## Fee accounting

Per-bucket balances accumulate inside the contract and are flushed on `distribute` or on threshold crossings inside `collect`. This amortizes the cost of split transfers across many operations, particularly important for high-frequency attestation flows.

```solidity theme={"system"}
uint256 pendingTreasury;
uint256 pendingBurn;
uint256 pendingValidatorPool;
uint256 flushThreshold; // e.g. 10_000 NOTA
```

When any pending balance crosses `flushThreshold`, the next `collect` auto-flushes all three. `distribute` forces a flush regardless.

## Validation

`setSplit` reverts if `treasuryBps + burnBps + validatorPoolBps != 10000`. `setFeeTable` reverts if any fee exceeds the governance-set absolute cap (e.g., `500_000 NOTA`) to protect against malicious or mistaken proposals.

## Integration wiring

`FeeManager` knows three callers by address, set at initialization:

| Caller contract      | Allowed ops                         |
| -------------------- | ----------------------------------- |
| `NotaRegistry`       | Register, Update                    |
| `VerificationEngine` | Verify\*, DisputeBond\*, refund     |
| `SlashingManager`    | Slash-fee routing (when applicable) |

Any other caller reverts on `collect`/`refund`/`distribute`. The wiring is set once via `initialize` and is immutable after that (changing it requires an upgrade).

## Events

```solidity theme={"system"}
event FeeCollected(
    OpKind indexed op,
    address indexed payer,
    uint256 fee,
    uint256 treasuryShare,
    uint256 burnShare,
    uint256 validatorShare
);
event FeeRefunded(OpKind indexed op, address indexed payee, uint256 amount);
event FeeTableUpdated(FeeTable table);
event SplitUpdated(Split split);
event TreasuryUpdated(address newTreasury);
event ValidatorPoolUpdated(address newPool);
event FeesDistributed(uint256 toTreasury, uint256 burned, uint256 toValidatorPool);
```

## SDK usage

```typescript theme={"system"}
import { Notareum, OpKind } from "@notareum/sdk";

const ntm = Notareum({ provider, signer, contracts });

// Quote before acting
const fee = await ntm.fee.quote(OpKind.VerifyEnhanced);
console.log(`Verification fee: ${formatNota(fee)} NOTA`);

// Fee table read
const table = await ntm.fee.getFeeTable();
const split = await ntm.fee.getSplit();

// Allowance dance (or use permit via NOTA token)
await ntm.nota.approve(ntm.fee.address, fee);
```

Governance-only writes are exposed on the SDK as `ntm.fee.governance.*` to keep the normal read API clean.

## Invariants

1. `treasuryBps + burnBps + validatorPoolBps == 10000`.
2. Every `collect` increments exactly one of pending buckets (or `distribute` flushes them), never two at once, never creating or destroying NOTA.
3. Refunds never exceed the original fee collected for the refunded operation.
4. Only pre-wired caller contracts can invoke `collect` / `refund`.

## Related pages

* [NotaRegistry](nota-registry.md)
* [VerificationEngine](verification-engine.md)
* [SlashingManager](slashing-manager.md)
* [Fee Model protocol doc](../protocol/fee-model.md)
