# GMV2 live callable functions

Verified 2026-09-18T13:07:34.532Z. This is a reference inventory, not permission to send transactions or change contract settings.

- Chain: Ink mainnet, 57073.
- Proxy (transaction target): `0x14Aec24CE62258FECDe22E928D8F37dD47165d4F`.
- Current implementation: `0xD95e662CCb953B2e7C946a5654Ed6Eaa469707C8`.
- Owner and treasury: `0xf805136A6E500830385Fb63AFD16A2eA869b5F1E`.
- Safe-block verification: 56238030, hash `0x64499e671edfa08c1c76ca8ca029fc6f878f067ff7c15c07ef3ef46d0cca79d2`.
- ERC-1967 implementation slot agrees with the public [deployment manifest](https://www.gm.ink/api/gm-v2/manifest).
- Live runtime, manifest and local compiled runtime hashes all equal `0x27ab4c3d723cd75e3bd2ff8364d99a7034091710bb4fef3af6ce749b8eab0b8f`.
- Solidity source hash matches the compiler artifact metadata: `0x68cf71851f5b63dbc6486fb2a8f9a17b9ccc289a6cc39d9a2666290dd2bd6852`. Compiler: 0.8.28+commit.7893614a.
- Live contract is activated and unpaused; authorization epoch 2.

## GM+ behavior

`gmPlusTo(address recipient)` and `agentGmPlusTo(address recipient)` already have no onchain cooldown or daily count limit. Each requires exactly **0.0005 ETH**. Repeated directed premium `gmFromX` requests have the same behavior. Five successful sends cost 0.0025 ETH in contract fees; ten cost 0.005 ETH, excluding gas. Sponsoring X gas does not pay these premium fees. The current X application's policy/parser may impose additional restrictions; those are separate from the contract inventory below.

`gmPlus()` and `agentGmPlus()` are the undirected premium daily actions and each retains a 24-hour cooldown. `gmUnlimitedTo(address recipient)` is the zero-fee, unranked directed action, and does not affect the ranked cooldowns.

## Common send rules

All send methods require an activated, unpaused contract and an active registered profile actor. Directed sends reject zero recipients, the calling actor and every wallet in the sender's own profile. Snapshot readiness is enforced, though the proof requirement expires 24 hours after the fixed legacy cutoff. Profiles share cooldowns across linked wallets. Agent checks use the profile controller's ERC-8004 credential; basic directed agent sends also require the recipient credential wallet to hold an identity. GM+ fees are forwarded to the treasury.

All successful ranked sends emit exactly one `GMExecuted` event. Unranked sends emit `GMUnlimitedExecuted` instead, do not consume ranked cooldowns, and must be excluded from ranked metrics. No onchain function checks X follows or blue badges; those are service-level rules.

## Inventory

The ABI contains **72 functions**. Constructor, events, errors, private/internal helpers and the separate identity-registry interface are not callable methods of this contract and are excluded. There is no GMV2 receive/fallback function, `gmUnlimited()`, `agentGmUnlimitedTo()`, `multicall()` or standalone `upgradeTo()`. The ERC1967 proxy delegates known calls; arbitrary ETH transfers to GMV2 are not a wallet-funding method. Fund the user's wallet, not this proxy.

Each declaration below includes all tuple members and names, the ABI state mutability and return fields. Tuple formatting is an expanded ABI signature, not Solidity struct-declaration syntax. All nonpayable/view calls require zero transaction value. Reads normally use `eth_call`, which does not submit a transaction.

### Everyday direct sends (9)

#### `gm`

```text
gm() nonpayable
```

Active actor; ranked human basic GM. Uses the shared profile lastGM 24-hour lane.

#### `gmTo`

```text
gmTo(address recipient) nonpayable
```

Active actor; nonzero recipient outside the sender profile. Ranked human basic GM; shares lastGM with gm().

#### `gmUnlimitedTo`

```text
gmUnlimitedTo(address recipient) nonpayable
```

Active actor; nonzero recipient outside the sender profile. Free unranked human GM; no cooldown read/write. Emits GMUnlimitedExecuted, not GMExecuted.

#### `gmPlus`

```text
gmPlus() payable
```

Active actor; exactly 0.0005 ETH. Ranked undirected premium GM; lastGMPlus has a 24-hour cooldown.

#### `gmPlusTo`

```text
gmPlusTo(address recipient) payable
```

Active actor; exactly 0.0005 ETH; nonzero recipient outside sender profile. Ranked directed premium GM; no cooldown and no contract daily count limit.

#### `agentGm`

```text
agentGm() nonpayable
```

Active actor; profile controller must hold an ERC-8004 identity. Ranked agent basic GM; lastAgentGM has a 24-hour cooldown.

#### `agentGmTo`

```text
agentGmTo(address recipient) nonpayable
```

Active actor; sender profile controller and recipient credential wallet must both hold ERC-8004 identities. Nonzero recipient outside sender profile; ranked, shares lastAgentGM with agentGm().

#### `agentGmPlus`

```text
agentGmPlus() payable
```

Active actor; sender profile controller must hold ERC-8004 identity; exactly 0.0005 ETH. Ranked undirected agent premium GM; lastAgentGMPlus has a 24-hour cooldown.

#### `agentGmPlusTo`

```text
agentGmPlusTo(address recipient) payable
```

Active actor; sender profile controller must hold ERC-8004 identity; exactly 0.0005 ETH. Nonzero recipient outside sender profile; recipient need not be an agent. Ranked, with no cooldown or contract daily count limit.

### Attested X sends (2)

#### `gmFromX`

```text
gmFromX((bytes32 profileId, address actor, address recipient, bool agent, bool premium, bool directed, uint256 nonce, uint256 deadline, uint256 maxFee, bytes32 requestId, uint256 authorizationEpoch, uint256 profileEpoch) request, bytes attestorSignature) payable
```

Caller must be request.actor, a member and active actor of request.profileId. Valid current X-attestor signature, current authorization/profile epochs, nonce, deadline and unused requestId required. maxFee must cover the required fee; actual value must be exactly 0 for basic or 0.0005 ETH for premium. Uses the same ranked human/agent, directed/undirected logic as direct calls; directed premium has no cooldown.

Canonical selector signature: `gmFromX((bytes32,address,address,bool,bool,bool,uint256,uint256,uint256,bytes32,uint256,uint256),bytes)`.

#### `gmUnlimitedFromX`

```text
gmUnlimitedFromX((bytes32 profileId, address actor, address recipient, bool agent, bool premium, bool directed, uint256 nonce, uint256 deadline, uint256 maxFee, bytes32 requestId, uint256 authorizationEpoch, uint256 profileEpoch) request, bytes attestorSignature) nonpayable
```

Same actor, attestor, nonce, epochs, expiry and replay checks as gmFromX, with a distinct signed type hash. Must be agent=false, premium=false, directed=true and maxFee=0. Free/unranked; no cooldown changes. Shares xNonces and usedXRequests with ranked X calls.

Canonical selector signature: `gmUnlimitedFromX((bytes32,address,address,bool,bool,bool,uint256,uint256,uint256,bytes32,uint256,uint256),bytes)`.

### Profiles, wallet permissions and snapshot proofs (6)

#### `registerProfile`

```text
registerProfile() nonpayable returns (bytes32 profileId)
```

Any wallet not already bound to a profile may register itself as controller and active actor. Snapshot root must exist; snapshot proof required only within the legacy cooldown window. Returns its deterministic profileId. Not gated by pause.

#### `linkActor`

```text
linkActor((bytes32 profileId, address actor, uint256 nonce, uint256 deadline, uint256 authorizationEpoch, uint256 profileEpoch) request, bytes controllerSignature, bytes actorSignature) nonpayable
```

Anyone may relay a request, but both the current profile controller and actor must sign the exact typed link. Valid profile, deadline, nonce, epochs and snapshot readiness required. Actor cannot be controller, already active, or bound to another profile. Permanently fixes membership; revocation does not free membership. Not gated by pause.

Canonical selector signature: `linkActor((bytes32,address,uint256,uint256,uint256,uint256),bytes,bytes)`.

#### `revokeActor`

```text
revokeActor(address actor) nonpayable
```

Only that actor profile controller. Cannot revoke the controller. Actor must have its active flag set. Disables actor, clears a pending transfer to it, and invalidates profile authorizations. Not gated by pause.

#### `transferProfileControl`

```text
transferProfileControl(address newController) nonpayable
```

Only current profile controller. New controller cannot be self or belong to another profile. Zero address cancels pending transfer. Starts a two-step transfer and invalidates profile authorizations. Not gated by pause.

#### `acceptProfileControl`

```text
acceptProfileControl(bytes32 profileId) nonpayable
```

Only the pending profile controller; cannot belong to another profile; snapshot readiness required. Preserves membership/history/cooldowns, revokes old controller and invalidates old delegates through a new actor generation. Not gated by pause.

#### `proveCooldowns`

```text
proveCooldowns(address wallet, (uint256 lastGM, uint256 lastAgentGM, uint256 lastGMPlus, uint256 lastAgentGMPlus) values, bytes32[160] siblings) nonpayable
```

Anyone may submit a valid sparse Merkle proof for a nonzero wallet. Snapshot must be configured; proof must not already exist; timestamps cannot exceed snapshot cutoff. Exactly 160 sibling nodes. Merges proven maxima into any existing profile. Not gated by pause.

Canonical selector signature: `proveCooldowns(address,(uint256,uint256,uint256,uint256),bytes32[160])`.

### Governance and lifecycle (13)

#### `initialize`

```text
initialize(address admin, address treasury_, address registry_, address attestor_) nonpayable
```

Initializer, one-time only; already consumed on live proxy and disabled on the implementation. Nonzero admin/treasury; registry must contain code; attestor must be nonzero and differ from admin. Establishes ownership, EIP-712 domain and paused state.

#### `configureSnapshot`

```text
configureSnapshot(bytes32 root, uint256 cutoffBlock, bytes32 cutoffBlockHash, uint64 cutoffTimestamp) nonpayable
```

Contract owner only, while paused; can succeed only once. Requires nonzero root/cutoff/hash/time, a past cutoff block and timestamp, and matching locally available block hash. Already configured on live proxy.

#### `activate`

```text
activate() nonpayable
```

Contract owner only, while paused, snapshot configured, not previously activated. Records activation time and unpauses. Already activated on live proxy.

#### `pause`

```text
pause() nonpayable
```

Contract owner only; contract must currently be unpaused. Stops sends; does not block every profile/read operation.

#### `unpause`

```text
unpause() nonpayable
```

Contract owner only; contract must be paused and previously activated.

#### `setTreasury`

```text
setTreasury(address newTreasury) nonpayable
```

Contract owner only, while paused. New treasury must be nonzero. Invalidates global authorizations.

#### `setIdentityRegistry`

```text
setIdentityRegistry(address newRegistry) nonpayable
```

Contract owner only, while paused. New registry must contain code. Invalidates global authorizations.

#### `setXAttestor`

```text
setXAttestor(address newAttestor) nonpayable
```

Contract owner only, while paused. Nonzero attestor distinct from current and pending owner. Invalidates global authorizations.

#### `invalidateAuthorizations`

```text
invalidateAuthorizations() nonpayable
```

Contract owner only, while paused. Increments global epoch, invalidating previous link/X signatures and linked-actor permissions; controllers remain directly active.

#### `transferOwnership`

```text
transferOwnership(address newOwner) nonpayable
```

Contract owner only. Sets pending owner; zero cancels transfer; current X attestor cannot be proposed. Two-step acceptance required.

#### `acceptOwnership`

```text
acceptOwnership() nonpayable
```

Only current pending owner. Completes two-step contract ownership transfer.

#### `renounceOwnership`

```text
renounceOwnership() view
```

Owner-only view function that always reverts OwnershipRenunciationDisabled. ABI-visible but ownership cannot be renounced.

#### `upgradeToAndCall`

```text
upgradeToAndCall(address newImplementation, bytes data) payable
```

Contract owner only, while paused; only through the active UUPS proxy. New implementation must pass UUPS UUID compatibility. Invalidates global authorizations, upgrades and optionally delegates data. Empty data requires zero value. No standalone upgradeTo function exists.

### Hash helpers and inherited introspection (7)

#### `hashActorLink`

```text
hashActorLink((bytes32 profileId, address actor, uint256 nonce, uint256 deadline, uint256 authorizationEpoch, uint256 profileEpoch) request) view returns (bytes32)
```

Anyone; EIP-712 digest for the full ActorLink, using current chain and called contract domain. Does not validate signatures or consume a nonce.

Canonical selector signature: `hashActorLink((bytes32,address,uint256,uint256,uint256,uint256))`.

#### `hashCooldownLeaf`

```text
hashCooldownLeaf(address wallet, (uint256 lastGM, uint256 lastAgentGM, uint256 lastGMPlus, uint256 lastAgentGMPlus) values) view returns (bytes32)
```

Anyone; hash for a wallet and four cooldowns. All-zero cooldowns return the common empty leaf. Includes chain and snapshot tag.

Canonical selector signature: `hashCooldownLeaf(address,(uint256,uint256,uint256,uint256))`.

#### `hashXRequest`

```text
hashXRequest((bytes32 profileId, address actor, address recipient, bool agent, bool premium, bool directed, uint256 nonce, uint256 deadline, uint256 maxFee, bytes32 requestId, uint256 authorizationEpoch, uint256 profileEpoch) request) view returns (bytes32)
```

Anyone; EIP-712 digest for ranked XRequest. Does not authorize, submit, or consume the request.

Canonical selector signature: `hashXRequest((bytes32,address,address,bool,bool,bool,uint256,uint256,uint256,bytes32,uint256,uint256))`.

#### `hashXUnlimitedRequest`

```text
hashXUnlimitedRequest((bytes32 profileId, address actor, address recipient, bool agent, bool premium, bool directed, uint256 nonce, uint256 deadline, uint256 maxFee, bytes32 requestId, uint256 authorizationEpoch, uint256 profileEpoch) request) view returns (bytes32)
```

Anyone; EIP-712 digest using the separate unlimited request type hash. Does not authorize, submit, or consume the request.

Canonical selector signature: `hashXUnlimitedRequest((bytes32,address,address,bool,bool,bool,uint256,uint256,uint256,bytes32,uint256,uint256))`.

#### `snapshotEmptyLeaf`

```text
snapshotEmptyLeaf() view returns (bytes32)
```

Anyone; returns the chain-specific empty cooldown leaf hash.

#### `eip712Domain`

```text
eip712Domain() view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)
```

Anyone; EIP-5267 domain fields. On proxy: GMV2, version 1, chain 57073, proxy verifying contract, zero salt and empty extensions.

#### `proxiableUUID`

```text
proxiableUUID() view returns (bytes32)
```

Anyone only when called directly on the implementation; deliberately reverts through the proxy. Returns the ERC-1967 implementation storage slot.

### Profile and authorization reads (13)

#### `profileOf`

```text
profileOf(address wallet) view returns (bytes32)
```

Anyone; immutable historical membership/profile ID for a wallet, or zero if none. Membership does not imply an active actor.

#### `profileController`

```text
profileController(bytes32 profileId) view returns (address)
```

Anyone; current profile controller address, or zero for unknown profile.

#### `pendingProfileController`

```text
pendingProfileController(bytes32 profileId) view returns (address)
```

Anyone; pending profile controller, or zero if none.

#### `profileEpoch`

```text
profileEpoch(bytes32 profileId) view returns (uint256)
```

Anyone; profile authorization epoch, or zero for unknown profile.

#### `actorGeneration`

```text
actorGeneration(bytes32 profileId) view returns (uint256)
```

Anyone; current profile-wide actor generation used to invalidate old delegates on controller recovery.

#### `linkNonces`

```text
linkNonces(bytes32 profileId) view returns (uint256)
```

Anyone; next actor-link nonce for the profile.

#### `xNonces`

```text
xNonces(address actor) view returns (uint256)
```

Anyone; next X request nonce for an actor, shared across ranked and unranked X sends.

#### `usedXRequests`

```text
usedXRequests(bytes32 requestId) view returns (bool)
```

Anyone; whether a requestId has been consumed by a successful ranked or unranked X send.

#### `isActorActive`

```text
isActorActive(address actor) view returns (bool)
```

Anyone; true only for a member with active flag and valid epoch/generation, except current controllers remain active across global epoch changes.

#### `lastGM`

```text
lastGM(bytes32 profileId) view returns (uint256)
```

Anyone; profile basic human GM lane timestamp. Shared by gm and gmTo, including corresponding X calls.

#### `lastAgentGM`

```text
lastAgentGM(bytes32 profileId) view returns (uint256)
```

Anyone; profile basic agent GM lane timestamp. Shared by agentGm and agentGmTo, including corresponding X calls.

#### `lastGMPlus`

```text
lastGMPlus(bytes32 profileId) view returns (uint256)
```

Anyone; profile undirected human premium GM lane timestamp. Directed premium sends do not read or modify it.

#### `lastAgentGMPlus`

```text
lastAgentGMPlus(bytes32 profileId) view returns (uint256)
```

Anyone; profile undirected agent premium GM lane timestamp. Directed premium sends do not read or modify it.

### Configuration and lifecycle reads (13)

#### `treasury`

```text
treasury() view returns (address)
```

Anyone; fee recipient address.

#### `identityRegistry`

```text
identityRegistry() view returns (address)
```

Anyone; ERC-8004 identity registry address.

#### `xAttestor`

```text
xAttestor() view returns (address)
```

Anyone; authorized X attestor address.

#### `authorizationEpoch`

```text
authorizationEpoch() view returns (uint256)
```

Anyone; global signature/actor authorization epoch.

#### `activatedAt`

```text
activatedAt() view returns (uint64)
```

Anyone; initial activation Unix timestamp; zero before activation.

#### `snapshotRoot`

```text
snapshotRoot() view returns (bytes32)
```

Anyone; configured cooldown sparse Merkle root.

#### `snapshotCutoffBlock`

```text
snapshotCutoffBlock() view returns (uint256)
```

Anyone; legacy snapshot cutoff block.

#### `snapshotCutoffBlockHash`

```text
snapshotCutoffBlockHash() view returns (bytes32)
```

Anyone; recorded legacy snapshot cutoff block hash.

#### `snapshotCutoffTimestamp`

```text
snapshotCutoffTimestamp() view returns (uint64)
```

Anyone; legacy snapshot cutoff Unix timestamp.

#### `snapshotVerified`

```text
snapshotVerified(address wallet) view returns (bool)
```

Anyone; whether this wallet has proven its snapshot leaf.

#### `owner`

```text
owner() view returns (address)
```

Anyone; current contract owner.

#### `pendingOwner`

```text
pendingOwner() view returns (address)
```

Anyone; proposed contract owner or zero.

#### `paused`

```text
paused() view returns (bool)
```

Anyone; whether sends are paused.

### Public constant getters (9)

#### `GM_FEE`

```text
GM_FEE() view returns (uint256)
```

Anyone; constant 500000000000000 wei (0.0005 ETH).

#### `COOLDOWN`

```text
COOLDOWN() view returns (uint256)
```

Anyone; constant 86400 seconds (24 hours).

#### `SOURCE_DIRECT`

```text
SOURCE_DIRECT() view returns (uint8)
```

Anyone; constant 0.

#### `SOURCE_X`

```text
SOURCE_X() view returns (uint8)
```

Anyone; constant 1.

#### `SNAPSHOT_TAG`

```text
SNAPSHOT_TAG() view returns (bytes32)
```

Anyone; keccak256 of GMV2_COOLDOWN_SNAPSHOT_V1.

#### `ACTOR_LINK_TYPEHASH`

```text
ACTOR_LINK_TYPEHASH() view returns (bytes32)
```

Anyone; constant EIP-712 ActorLink type hash.

#### `X_REQUEST_TYPEHASH`

```text
X_REQUEST_TYPEHASH() view returns (bytes32)
```

Anyone; constant EIP-712 ranked XRequest type hash.

#### `X_UNLIMITED_REQUEST_TYPEHASH`

```text
X_UNLIMITED_REQUEST_TYPEHASH() view returns (bytes32)
```

Anyone; constant EIP-712 unranked XUnlimitedRequest type hash.

#### `UPGRADE_INTERFACE_VERSION`

```text
UPGRADE_INTERFACE_VERSION() view returns (string)
```

Anyone; inherited constant string 5.0.0.

## Source references

- [GMV2 source](https://github.com/sergio-inkfnd/gm/blob/7e821941213210c6e4209b25dceb1d09c665d97f/contracts/GMV2.sol)
- [Complete ABI](https://github.com/sergio-inkfnd/gm/blob/7e821941213210c6e4209b25dceb1d09c665d97f/contracts/abi/GMV2.json)
- [Live proxy on Ink Blockscout](https://explorer.inkonchain.com/address/0x14Aec24CE62258FECDe22E928D8F37dD47165d4F)
- [Live implementation on Ink Blockscout](https://explorer.inkonchain.com/address/0xD95e662CCb953B2e7C946a5654Ed6Eaa469707C8)
- [Public deployment manifest](https://www.gm.ink/api/gm-v2/manifest)

This audit made read-only calls only. No signatures, approvals, transactions or configuration changes were submitted.
