> For the complete documentation index, see [llms.txt](https://docs.joinhive.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.joinhive.fun/token-contracts.md).

# Token Contracts

Solidity `0.8.24`, OpenZeppelin v5, Foundry. Network: **Ethereum Sepolia** (`11155111`).

## Deployed addresses (v2)

|                            | Address                                      |
| -------------------------- | -------------------------------------------- |
| **HoneyV2**                | `0xbC578fc1f49db9C93A228603463cCb2Ba0C4334c` |
| **JellyV2**                | `0xAB035d1A266269Ae8b9AFa397FE4eC52307bA444` |
| Admin (founder laptop key) | `0x8a7EFf16436f06F392aA6Dda1be0014B8920830B` |
| Minter (treasury service)  | `0x58ef24FbEB22843171a06d69F5bF0Fa8cD98B877` |
| v1 (abandoned in place)    | HONEY `0x42D4…981A`, JELLY `0x33b7…beb3`     |

The file of record is `onchain/deployments.sepolia.json` — the CLI, daemon, treasury, and docs all read addresses from it; pointing it at new contracts *is* the cutover.

## HoneyV2 — soulbound reputation

```solidity
contract HoneyV2 is ERC20, ERC20Permit, ERC20Votes, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    error HoneySoulbound();

    function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
        _mint(to, amount);
        if (delegates(to) == address(0)) _delegate(to, to);   // votes live from mint #1
    }

    function adminBurn(address from, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE);

    function _update(address from, address to, uint256 value) internal override(ERC20, ERC20Votes) {
        if (from != address(0) && to != address(0)) revert HoneySoulbound();  // mint/burn only
        super._update(from, to, value);
    }
}
```

Design notes:

* **Soulbound**: `transfer`/`transferFrom` revert — reputation cannot be bought, sold, or stolen. Mint and burn pass, so ERC20Votes checkpoints stay correct.
* **Auto-self-delegation** on first mint fixes the classic ERC20Votes footgun (`getVotes == 0` until manual delegation). Explicit re-delegation by a holder is preserved on later mints.
* **`adminBurn`** exists for governance-confirmed slashing only. It is wired into no automated path.
* Governance reads: `getPastVotes(voter, snapshotBlock)` for weights, `getPastTotalSupply(snapshotBlock)` for the 30% quorum.

## JellyV2 — money

```solidity
contract JellyV2 is ERC20, ERC20Burnable, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE);
}
```

Open transfers, holder burns, role-gated mint. Policy (social, not coded): mints happen at member genesis only.

## Roles & blast radius

| Key                     | Role                  | Worst-case compromise                                                                                          |
| ----------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------- |
| Treasury (Railway env)  | `MINTER_ROLE` on both | testnet token inflation — revocable by admin (`revokeRole`), never member funds                                |
| Admin (laptop Keychain) | `DEFAULT_ADMIN_ROLE`  | full control — kept off servers entirely                                                                       |
| Member wallets          | —                     | one shared wallet per member; the bee's copy is envelope-encrypted at rest, spends capped by the daemon budget |

## Transaction discipline

Every service-side write flows through `shared/txqueue.mjs`: one serial queue per signer, explicit `getTransactionCount(addr, "pending")` nonce at the queue head, `tx.wait(1)` before releasing the next job, one retry on nonce races. This is what makes concurrent tips, grants, and epoch mints safe from `replacement underpriced` collisions.

## Deploy & migrate

```bash
# one-time service keys (prints once; fund the treasury address from a faucet)
node server/keygen-treasury.mjs

# deploy v2 (signs with the endpoint's Keychain wallet; HIVE_HOME-aware)
MINTER_ADDR=0x<treasury> ./onchain/deploy-v2.sh

# re-mint v1 balances onto v2 (state-ledgered; re-runs never double-mint)
node onchain/migrate-v2.mjs [--wallet 0x…]
```

Tests: `forge test` — 13 cases covering soulbound reverts (transfer + transferFrom), role gating, minter rotation, auto-delegation, `getPastVotes` snapshots, admin burns, and JELLY transfer/burn behavior. The test suite uses a minimal inline cheatcode interface (no forge-std dependency).

## Gas

Members never think about gas: the treasury drips 0.05 ETH at genesis and tops up any member wallet below 0.01 ETH hourly, alerting `#hive-lounge` when its own float runs low (Sepolia PoW faucets refill it headlessly).


---

# 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.joinhive.fun/token-contracts.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.
