# Verify our contracts — source to deployed runtime

This kit targets exactly two contracts on Robinhood chain **4663**, for token
`0xAF10A9639499aB029B05149844373091E3F7c975`. It is not a production-safety attestation.

| Contract | Address | Deployed runtime bytes | SHA256 of decoded runtime bytes |
| --- | --- | ---: | --- |
| GMContractCustodyV5 | `0x9f54c5b7372f4920368ed165f00de643bf5f5d73` | 8155 | `4413a71eeeb5212c58c1c4684f8c7abe541e2df3c0f1daafba85149ff8e50ee3` |
| GMDrandQuicknetVerifier | `0x567a4a4e8aae79f4068fd65495e4fc465fe1c856` | 4456 | `e207cf195489a91e23ef50bd7ea6b4106ac086b5a7e42aa2e42871651da02815` |

Explorer: https://rh-scan.com/address/0x9f54c5b7372f4920368ed165f00de643bf5f5d73
and https://rh-scan.com/address/0x567a4a4e8aae79f4068fd65495e4fc465fe1c856 .
Explorer links are navigation, not a claim of explorer source verification.
Custody deployment transaction:
`0x630bc658e63e5a28b5b2970020dcc9b1b2f78eae4b3fb039bf85ba787a7ebb6a`, block **64454830**.
The drand identity is established here by its exact address and runtime, not by
an asserted original deployment transaction. The CLI checks runtime, not receipts.

## Prerequisites and compiler provenance

- Python **3.9+**, standard library only; no pip/npm packages. Tested with the
  existing Python environment, not a fresh-machine installation.
- For the live read option, an installed `curl` supporting `--max-filesize`, and
  a user-chosen HTTPS JSON-RPC endpoint for chain 4663. No endpoint is contacted
  by the default offline command. Loopback HTTP is allowed for local providers/tests.
- Linux x86-64 Solidity **0.8.34+commit.80d5c536**. Compiler SHA256:
  `d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39`.
  The compiler is **not bundled**. Other architectures/binaries are not silently
  accepted: this reproducibility route pins the exact Linux amd64 binary.
- Optimizer enabled, **200 runs**, EVM **cancun**; `viaIR` unset (false default),
  metadata defaults unchanged. Exact settings/output selection and all five
  embedded source units are in `solc-input.json`. No linked external libraries,
  npm dependencies or import downloads are used. Do not alter source paths.
- Vendored Solidity dependency: [randa-mu/bls-solidity](https://github.com/randa-mu/bls-solidity)
  commit `9e10df92d631fab9c46f0ce9cd5c445f857bedcb`, MIT; `BLS2.sol` and
  `Precompiles.sol`, with original `LICENSE` and `PROVENANCE.md`. The verifier's
  quicknet key and chain hash are constants in its source. This dependency is
  described by its upstream as experimental and unaudited.

`compiler-provenance.json` retains the exact official build entry, index URL,
retrieval time and index digest. Independently check the build entry against
https://binaries.soliditylang.org/linux-amd64/list.json (or Solidity's independent
release records); a provenance file from this same website is not independent trust.

Optional compiler acquisition, from inside the extracted directory:

```sh
curl --fail --show-error --location \
  'https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.8.34+commit.80d5c536' \
  --output solc-0.8.34
python3 -I -c 'import hashlib,pathlib,sys; p=pathlib.Path("solc-0.8.34"); sys.exit(0 if hashlib.sha256(p.read_bytes()).hexdigest()=="d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39" else "STOP: compiler hash mismatch")' && chmod +x solc-0.8.34
```

Review scripts before running them. The verifier independently repeats the compiler
hash check **before executing it**. These acquisition instructions were not tested
as a fresh installation; the existing pinned compiler was actually used for builds.
A failed download, missing tool, compiler mismatch or RPC failure is not success.

## Rebuild and compare (offline)

Unzip `contract-verification-kit.zip`, then enter `gm-contract-verification-kit`:

```sh
python3 -I -B verify.py --solc ./solc-0.8.34
```

Or supply the absolute path of an already installed, identical compiler. This:

1. Checks `files.sha256.json`, then exact standalone-source/embedded-input equality.
2. Executes the pinned solc with the shipped standard JSON input, including AST
   and compiler-produced `immutableReferences`. No build artifact is trusted as
   a substitute for compilation.
3. Compares ABI, creation bytecode, runtime template, slot offsets/lengths and AST
   immutable-name mapping against `artifacts.json` for both contracts.
4. Patches custody's **41 compiler slots across 10 immutable groups** using
   `immutables.json`, with exact 32-byte words. It rejects missing roles, malformed
   slots and overlap. The drand verifier has **no immutable slots**.
5. Compares **every byte**, including Solidity metadata, to the captured runtime
   `.hex` files, and checks decoded byte counts/SHA256. It never masks immutable
   regions or tolerates unexplained differences. Creation hashes/counts refer to
   compiler creation code **without constructor arguments**, not transaction calldata.

Exit **0** reports `sourceBuild: Passed`, `recordedRuntime: Passed`, and
`liveChain: Not checked`. It only proves correspondence to the included snapshot.
Exit **1** and `FAILED` is refusal; no success is printed for a partial run.

## Compare against your own provider (read-only)

Set `GM_RPC_URL` locally to an endpoint you trust, then run:

```sh
python3 -I -B verify.py --solc ./solc-0.8.34 --rpc-env GM_RPC_URL
```

No wallet, signing, funding or transaction broadcast. The only RPC methods are
`eth_chainId`, `eth_blockNumber`, `eth_getBlockByNumber`, and `eth_getCode`.
The URL is read from the environment and is not printed or passed in process
arguments. The provider sees your reads. The script checks chain 4663, reads both
addresses at one numbered block, compares exact rebuilt runtime bytes, then
re-reads that block's hash. A changed hash, wrong chain, empty/wrong code, malformed
reply or transport error fails closed. It does not infer finalized consensus from
a provider reply. Run against independent providers if appropriate.

Only this optional successful run reports `liveChain: Passed (provider-backed,
not a consensus proof)` and the actual block number/hash checked. `manifest.json`
records the kit's original snapshot separately; it is not an evergreen live badge.

## Custody immutable roles

The exact values are in `immutables.json`; the corresponding AST IDs/slots are
in `artifacts.json` and are freshly regenerated by solc on every verification.

| Solidity immutable | Meaning |
| --- | --- |
| PONS_ESCROW | Bound Pons fee escrow |
| GM_TOKEN | Bound AF10 token |
| USDG | Bound quote/payout token |
| RESERVE_SAFE | Reserve payout address; the name does not prove it is a Safe |
| RECOVERY_SAFE | Recovery-authority address; the name does not prove it is a Safe |
| COMMITTER | Authorized commitment address |
| DRAW_VERIFIER | Bound drand verifier above |
| MINIMUM_CLAIMABLE_USDG | 2500000 base units, 2.5 USDG at 6 decimals |
| PONS_CURVE | Bound launch curve |
| PONS_FACTORY | Bound launch factory |

These are public immutable bindings, not a disclosure of keys. Matching code
checks these encoded values but does not verify current balances, pause/route
state, operator readiness, key control or third-party contract implementations.

## Limits and licenses

- Byte count alone is **not proof**. A hash is useful only against a trusted
  reference. A ZIP, checksum, script and source served by the same site can all
  be replaced together; same-origin checksums detect corruption, not compromise.
  Independently review sources/compiler provenance and compare via your own RPC.
- Source/runtime agreement is **not an audit or a guarantee of no bugs**, secure
  permissions, safe economics or correct cryptography. No production attestation
  is made. Vendored BLS primitives remain experimental/unaudited.
- It does not prove full holder eligibility/completeness, correctness of a
  particular payout or randomness signature. Use the separate round-verification
  kit for its narrower per-round checks and read those limitations too.
- No original verifier deployment receipt verification is claimed. No external
  Pons/USDG source equivalence audit, proxy/delegate audit or consensus proof is
  included. This kit targets the two explicit current addresses only.
- All GM Solidity files retain their MIT SPDX headers. `SOURCE-NOTICES.md`
  supplies the MIT terms and preserves the dependency's original notice.
- The archive is an explicit allowlist: sources, notices, standard input,
  compiler provenance, artifact projection, immutable values, public runtimes,
  manifest and read-only CLI. No compiler binary, wallet UI, unsigned signing
  package, credentials, private logs or operational state is included.
