> For the complete documentation index, see [llms.txt](https://docs.arcv.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.arcv.network/5.-smart-contracts-and-arc-network-settlement/5.1-contract-architecture.md).

# 5.1 Contract Architecture

ARCVDataBountyRegistry is a native-value escrow and provenance registry. It accepts a sponsor-funded campaign, records one contributor's payable submission at a time, and releases the campaign's fixed reward when an authorized validator approves that registered submission. The external $ARCV token is a configurable reference; the registry neither creates a token nor uses token balances to fund payouts.

This chapter describes the repository implementation, not a certified production deployment. No verified registry deployment address, deployment receipt, or explorer verification record has been established by this documentation release. “Designed for Arc” and “deployed and verified on Arc” are distinct claims.

## Build and execution model

| Component               | Repository configuration                   | Operational meaning                                          |
| ----------------------- | ------------------------------------------ | ------------------------------------------------------------ |
| Compiler                | Solidity 0.8.28                            | Exact compiler version is pinned                             |
| EVM target              | Cancun                                     | Shanghai is not the configured target                        |
| Optimizer               | Enabled, 200 runs                          | Preserve these settings when reproducing deployment bytecode |
| Authorization           | OpenZeppelin Contracts 5.4.0 AccessControl | Role membership authorizes operations                        |
| Payout guard            | OpenZeppelin ReentrancyGuard               | Applied to validateAndDisburse                               |
| Deployment form         | Constructor-based contract                 | No proxy, initializer, or upgrade entry point                |
| Settlement denomination | Native value                               | Currency depends on the chain where the contract runs        |

The source does not enforce a chain-ID restriction. On Arc mainnet, native value represents USDC; the same bytecode on a different EVM chain would handle that chain's native currency. Clients must validate the network and deployment rather than infer currency from a contract name.

Cancun is a bytecode compatibility choice. An interface does not tell an integrator which compiler settings produced the deployed runtime. Maintain the source revision, dependency commits, compiler metadata, constructor arguments, and runtime code identity together.

## Native USDC escrow and msg.value

[Arc's official network reference](https://docs.arc.io/arc/references/connect-to-arc) identifies mainnet chain ID 5042 and native USDC with 18 decimal places. The registry receives native value through the payable createBounty function. It does not call an ERC-20 transferFrom method, so a sponsor does not approve a token allowance for this escrow flow.

Let N be targetCount and r be rewardPerSample, both unsigned integers. The required value is:

```
E_initial = N * r
msg.value = E_initial
r = advertised_native_USDC_reward * 10^18
```

For 100 payable records at 0.25 USDC each, r is 250000000000000000 base units and the deposit is 25 USDC. Both underpayment and overpayment revert. Transaction gas is paid in addition to the deposit. Use integer conversion from decimal strings; do not calculate a large escrow with binary floating-point arithmetic.

The Solidity denomination keyword ether used in local tests means a multiplier of 10^18. It does not change the native currency to ETH. Similarly, a six-decimal ERC-20 USDC representation must not be used to encode msg.value.

Creation is one atomic operation: specification checks, exact deposit validation, identifier allocation, campaign storage, liability accounting, and BountyCreated emission either all succeed or all revert. There is no intermediate contract state where an unfunded campaign exists.

## Storage model and interpretation

| Storage                    | Fields or value                                                                                | Interpretation                                              |
| -------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Bounty                     | sponsor, targetCount, rewardPerSample, remainingEscrow, pendingCount, paidCount, dataSchemaURI | One funded campaign and its outstanding liability           |
| Dataset                    | bountyId, dataSha256, arweaveTxId, contributor, status                                         | One registered payable record                               |
| bountyCount / datasetCount | Monotonically increasing integers                                                              | IDs begin at one                                            |
| totalEscrow                | Aggregate unpaid campaign liabilities                                                          | Accounting value, not necessarily the entire native balance |
| usedHashes                 | Digest to boolean                                                                              | Global reservation within one registry                      |
| usedArweaveTxIds           | Keccak-256 of identifier text to boolean                                                       | Separate archival-identifier reservation                    |
| arcvToken                  | Nonzero external address                                                                       | Reference only; no transfer, swap, or burn behavior         |

The campaign has no explicit lifecycle enum. “Created,” “in progress,” and “fully paid” are views derived from counters. The dataset enum is explicit: None=0, Pending=1, Paid=2, Rejected=3. A getter for an unknown ID returns default values; a successful read alone does not prove that a record exists.

The schema URI is stored as supplied. A nonempty value passes the contract check even if it is unreachable, mutable, or not a JSON Schema. Pin schema content and its digest in the off-chain campaign record. The current ABI does not store a separate schemaHash.

## Access-control matrix

| Operation                      | DEFAULT\_ADMIN\_ROLE      | BUNDLER\_ROLE             | VALIDATOR\_AGENT\_ROLE  | Any address         |
| ------------------------------ | ------------------------- | ------------------------- | ----------------------- | ------------------- |
| Create funded bounty           | Yes                       | Yes                       | Yes                     | Yes                 |
| Register dataset               | Only with bundler grant   | Yes                       | Only with bundler grant | No                  |
| Approve and pay                | Only with validator grant | Only with validator grant | Yes                     | No                  |
| Reject pending dataset         | Only with validator grant | Only with validator grant | Yes                     | No                  |
| Set external token reference   | Yes                       | No                        | No                      | No                  |
| Grant/revoke operational roles | Yes                       | No                        | No                      | No                  |
| Renounce own role              | For own membership        | For own membership        | For own membership      | Only own membership |
| Upgrade, pause, cancel, refund | Absent                    | Absent                    | Absent                  | Absent              |

DEFAULT\_ADMIN\_ROLE is bytes32 zero. BUNDLER\_ROLE and VALIDATOR\_AGENT\_ROLE are Keccak-256 hashes of their exact uppercase names. The constructor grants only the default administrator role. An administrator is not automatically a validator or bundler, although it can grant those roles to itself.

The administrator of each role is the default administrator unless changed by internal code; this registry exposes no external role-admin setter. The default administrator role administers itself. This is powerful immediate authority, not a timelocked governance framework.

BUNDLER\_ROLE authorizes submitDataset, not payments. There is no batch registration or batch disbursement method. A relayer can orchestrate multiple individual transactions, but cannot describe them as one atomic multi-task settlement. A relayer without validator membership cannot call validateAndDisburse.

A compromised bundler can reserve funded capacity with fabricated metadata; the contract cannot independently inspect the archive. A compromised validator can pay any pending entry without demonstrating rubric correctness. An administrator can grant both powers to another account. Separation of duties improves operations but does not make the system trustless.

## Administration and emergency response

Constructor arguments reject zero addresses for the initial administrator and external token. setARCVToken also rejects zero. The inherited grantRole function does not impose a zero-address rejection, a two-step acceptance ceremony, or a delay. Therefore the statement “all administrative role transfers reject zero addresses” would be false.

Role rotation is a sequence: grant the replacement administrator, verify its ability to perform authorized operations, then revoke the old administrator. No built-in transferAdmin function coordinates this sequence. Revoking or renouncing the last viable administrator can permanently remove role-management capability.

Revoking compromised operational roles can stop those signers, but it is not an emergency pause. Public bounty creation remains callable, existing liabilities remain, and there is no emergency withdrawal. A multisignature administrator can be chosen as the constructor argument; its actual threshold and owners must be verified separately. The registry does not enforce a multisignature quorum.

No upgrade permission exists. Changing arcvToken changes only an address reference. Adding refunds, fee caps, or pause behavior requires a separately reviewed implementation and migration design, not an administrative parameter update.

## Implemented state transitions

```
Sponsor
  |
  | createBounty(N, r, schemaURI), msg.value = N*r
  v
Created and escrowed campaign
  |
  | off-chain assignment, evaluation, archival
  | bundler: submitDataset
  v
In progress: one Pending dataset, one reserved slot
  |
  +-- validator: rejectDataset ----------------> Rejected
  |                                              |
  |                                      slot becomes available
  |                                      escrow remains locked
  |
  +-- validator: validateAndDisburse
         |
         +-- recipient call fails ------------> transaction reverts
         |                                      dataset stays Pending
         |
         +-- recipient call succeeds ---------> Paid / Disbursed
                                                counters and liabilities updated
```

There is no separately stored Validated state: approval and disbursement happen within the same transaction. A successful off-chain judgment is not yet an on-chain Paid state. A failed recipient call reverts the whole operation.

For a bounty with target N, paid count a, and pending count p:

```
0 <= p + a <= N
remainingEscrow = (N - a) * r
totalEscrow = sum(all campaign remainingEscrow)
registry native balance >= totalEscrow
```

Registration increments p without spending escrow. Payment decrements p, increments a, and decreases both campaign and global liabilities by r. Rejection decrements p but does not change liabilities. Forced native transfers can make balance exceed totalEscrow; they do not create additional campaign credit.

## Expiry, cancellation, and liveness gap

The requested timeout guarantee is not satisfied by this implementation. It has no deadline field, expiry transition, cancelBounty, sponsor withdrawal, or emergency recovery method. Unused escrow can remain locked indefinitely. Validator availability, valid submissions, and a payable recipient are required for eventual payout.

The following is a future lifecycle requirement, not an implemented path:

```
Funded -> Open -> deadline reached -> Expired
             |                         |
             | accepted work           | close reservations under defined policy
             v                         v
          Payout                  Refundable liability
                                       |
                             sponsor claim / alternate receiver
                                       v
                                    Refunded
```

A production refund design must define the exact timestamp boundary, treatment of Pending records, validator grace periods, already earned rewards, and race ordering between settlement and cancellation. It must prevent a sponsor from reclaiming money already owed to accepted workers. A pull-based refund can preserve a claim when a receiving contract rejects payment; merely adding a timeout does not guarantee a transfer succeeds.

The desired liveness property should be stated precisely: after a bounded deadline and adjudication interval, the sponsor can reclaim the unallocated liability without requiring validator cooperation. This requires code and tests absent today. It must not be represented as an audited invariant of the existing contract.

See [Hash Registry & Replay Defense](/5.-smart-contracts-and-arc-network-settlement/5.2-hash-registry-and-replay-defense.md) for commitment scope and [Security & Test Suite](/5.-smart-contracts-and-arc-network-settlement/5.3-security-and-test-suite.md) for evidence and missing coverage.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.arcv.network/5.-smart-contracts-and-arc-network-settlement/5.1-contract-architecture.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
