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

# AccountCore

> Identity, root-wide permissions, custody, and fee policy.

AccountCore holds custody and identifies every root and child by a nonzero `uint40` account ID.
Children are ledger entries, with no deployed contract, wallet address, or signer registry.
This is a fresh-deployment model: its storage layout and API are incompatible with the former address-keyed model.

Physical custody flows use an external global USD36 limiter with per-token price sources.
Ordinary withdrawals consume 24-hour deposit credit, then a capped drip allowance. Approved root-owner-signed payouts bypass those pools but still require valid pricing and active releases. See [WithdrawalLimiter](/contracts/withdrawal-limiter).

## Identity and custody

`rootAccountIdOf(owner)` resolves an owner's one root ID, or zero before registration.
Each ID stores its owner, root ID and sequence. A root points to itself and has sequence zero;
children share the root owner and have consecutive sequences starting at one. IDs and sequences are never reused.
There can be at most 65,535 children per root. `getSubaccounts(rootId)` returns their IDs in creation order.

Free balances and active-order reserves are keyed by account ID and token. Native MON uses `address(0)`.
Trading and passive liquidity operate on each child's own balance and reserves; sharing signers does not pool collateral.
The existing root-wide builder and fee policies still resolve through the target account's root ID.
Positive builder fees credit the builder's root free balance, registering that root if needed, and emit
`SpotReserveUpdated` before `BuilderFeeAccrued`. Builders withdraw through the root-only withdrawal API;
there is no separate builder-fee claim ledger. Zero-fee attribution does not register a builder root.

## External funding

There are exactly two deposit entrypoints:

* `deposit(address rootOwner, address token, uint256 amount)` registers the owner's root if necessary.
* `deposit(uint40 rootAccountId, address token, uint256 amount)` requires an existing root ID.

Anyone may fund a root. The payer receives no authority over it. Both overloads support ERC20 and native assets.
A child ID is rejected, including when its owner is the caller. SpotPeriphery exposes the same two overloads.

`withdraw(uint40 rootAccountId, address token, uint256 amount, address recipient)` only accepts roots and pays the explicit recipient.
Reject zero and AccountCore itself. Recipients need no registration or permissions; registered recipients receive an external payout, not internal balance credit.
This replaces the three-argument signature; callers must pass their own address explicitly to retain caller payouts.
The caller must be the root owner or a live root `WITHDRAW`/`ADMIN` signer. No child can withdraw, even through its owner.

`transferBetweenAccounts(fromId, toId, token, amount)` moves free balance within one family. It requires the root
owner or a live root `INTERNAL_TRANSFER`, `WITHDRAW` or `ADMIN` signer. Root-to-child, child-to-root and sibling transfers use the same
check. Thus funding a child and withdrawing its proceeds go through the root. Reserved assets must first be released.
These restrictions apply to external funding; settlement and passive-liquidity releases can credit children normally.

## One signer registry per root

All grants live under the root ID. There are no child-specific signers.

| Authority | Scope |
| - | - |
| Root owner | Full control over the family, subject to root-only external funding |
| `TRADE` | Root and every current or future child: place, replace, cancel, swap, passive liquidity; also create children |
| `ADMIN` | All defined roles: manage root grants, create children, trade across the family, transfer internally and withdraw from the root |
| `INTERNAL_TRANSFER` | Move free balance between IDs in the same family |
| `WITHDRAW` | Withdraw from the root to the explicit recipient and transfer internally within the family |

The hierarchy is evaluated when checking authority: ADMIN includes TRADE, WITHDRAW and INTERNAL\_TRANSFER;
WITHDRAW includes INTERNAL\_TRANSFER. Stored grants and authorization events retain the exact granted bits.
TRADE and INTERNAL\_TRANSFER do not imply higher permissions. Deposits remain permissionless funding.
Expiry and revocation apply to the entire family immediately. Adding a child does not change existing grants.
`isAuthorizedAccountSignerById` is the canonical trading authorization query. For delegated signers, child-ID queries only evaluate `TRADE`; check non-trading roles against the root ID. Internal family transfers authorize against that root rather than testing a child for `INTERNAL_TRANSFER`. A zero account ID in orderbook entrypoints
retains the caller's own root convenience path; it never selects a root based on delegated authority.

Signer administration continues to identify the root by its owner address, including the EIP-712 grant/revoke flows.
Only the owner can bootstrap an unregistered root. Each successful grant or revocation increments the root's
authorization epoch. `accountAuthorizationEpoch(accountId)` returns that epoch for either root or child and rejects
unknown IDs. `accountSignerAuthorizationNonces(rootOwner)` provides the owner-address lookup, returning zero before
registration. Signed trading actions bind both the actual target ID and this root epoch. Reauthorizing a revoked signer
does not revive earlier intents or stored triggers. Creating a child does not invalidate trading intents.

## Child creation

`createSubaccount(rootOwner)` accepts the owner or a live root ADMIN/TRADE signer. Only the owner can bootstrap a
missing root. The signed entrypoint accepts the same authorizers, checked at execution time:

```solidity theme={null}
createSubaccountBySig(rootOwner, authorizer, subaccountSeq, authNonce, deadline, signature)
```

Its EIP-712 domain is `KuruAccountCore`, version `1`, the current chain ID and AccountCore proxy address. The type is:

```text theme={null}
CreateSubaccount(address rootOwner,address authorizer,uint16 subaccountSeq,uint256 authNonce,uint256 deadline)
```

`authNonce` must match the root epoch. `subaccountSeq` must equal the next sequence, so both direct and signed
creation consume it. Two requests for the same sequence compete: after one succeeds, the other must be signed again.
This avoids another nonce mapping. Signatures support EOAs and ERC-1271 contract authorizers through Solady.
The old child-address consent flow and its typed message are removed. Names and other display metadata remain offchain.

## Contract boundaries and integration

`IAccountCore` owns identity, root authorization, custody and fee policy. `ISpotBalanceAccount` exposes verified
orderbook reserve and settlement operations. SpotPeriphery is unprivileged. KuruTradingWallet validates signed
intents against the target ID and root epoch before forwarding through normal orderbook checks.
Token configuration, fee rounding, order packing and matching economics are unchanged.

Integrators must regenerate ABIs, pass IDs for balances, transfers, withdrawals and trades, and use owner addresses
only for root lookup/bootstrap and root administration. Read `AccountRegistered(accountId, rootAccountId, rootOwner,
subaccountSeq)` to index every account and `SubaccountCreated(rootAccountId, subaccountId, authorizer)` for creation
provenance. Child IDs are not deposit addresses. SDK/frontend/indexer changes must ship with the new deployment.

Source: [Account architecture at main](https://github.com/Kuru-Labs/kuru-contracts-perps/blob/42ef525/docs/AccountArchitecture.md).

## Callable reference

Signatures and parameter types below are generated from the reviewed SDK 0.2.0 ABI (contract revision `cdac5ae1`). These are Solidity return values: SDK write methods return a transaction hash and require receipt reconciliation. Viem decodes small Solidity integers as numbers; the SDK normalizes account IDs to `bigint` on its account-client methods.

<AccordionGroup>
  <Accordion title="rootAccountIdOf(address)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `argument0` | `address` |

    **Returns:** `uint40`.
  </Accordion>

  <Accordion title="getAccountOwner(uint40)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |

    **Returns:** `address`.
  </Accordion>

  <Accordion title="getAccountRootId(uint40)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |

    **Returns:** `uint40`.
  </Accordion>

  <Accordion title="getAccountSubaccountSeq(uint40)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |

    **Returns:** `uint16`.
  </Accordion>

  <Accordion title="getSubaccounts(uint40)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `rootAccountId` | `uint40` |

    **Returns:** `uint40[]`.
  </Accordion>

  <Accordion title="getBalance(uint40, address)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |
    | `token` | `address` |

    **Returns:** `uint256`.
  </Accordion>

  <Accordion title="getSpotReservedBalance(uint40, address)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |
    | `token` | `address` |

    **Returns:** `uint256`.
  </Accordion>

  <Accordion title="deposit(address, address, uint256)">
    **Mutability:** `payable`. Permissionless funding of a root only. The owner-address overload registers a root if needed. ERC-20 assets require allowance; native MON requires exact transaction value. Pricing and token-enablement checks apply.

    | Parameter | Solidity type |
    | - | - |
    | `rootOwner` | `address` |
    | `token` | `address` |
    | `amount` | `uint256` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="deposit(uint40, address, uint256)">
    **Mutability:** `payable`. Permissionless funding of a root only. The owner-address overload registers a root if needed. ERC-20 assets require allowance; native MON requires exact transaction value. Pricing and token-enablement checks apply.

    | Parameter | Solidity type |
    | - | - |
    | `rootAccountId` | `uint40` |
    | `token` | `address` |
    | `amount` | `uint256` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="withdraw(uint40, address, uint256, address)">
    **Mutability:** `nonpayable`. Root owner or live root WITHDRAW/ADMIN authority. Debits root free balance and pays the explicit external recipient. Capacity, prices, release controls, and transfer checks apply.

    | Parameter | Solidity type |
    | - | - |
    | `rootAccountId` | `uint40` |
    | `token` | `address` |
    | `amount` | `uint256` |
    | `recipient` | `address` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="transferBetweenAccounts(uint40, uint40, address, uint256)">
    **Mutability:** `nonpayable`. Root owner or live root INTERNAL\_TRANSFER/WITHDRAW/ADMIN authority. Both IDs must share a root. Moves free balance only; no external token transfer.

    | Parameter | Solidity type |
    | - | - |
    | `fromAccountId` | `uint40` |
    | `toAccountId` | `uint40` |
    | `token` | `address` |
    | `amount` | `uint256` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="createSubaccount(address)">
    **Mutability:** `nonpayable`. Root owner or live root TRADE/ADMIN authority; only the owner can bootstrap a missing root. Returns a new numeric child ID and does not advance the root epoch.

    | Parameter | Solidity type |
    | - | - |
    | `rootOwner` | `address` |

    **Returns:** `uint40 subaccountId`.
  </Accordion>

  <Accordion title="createSubaccountBySig(address, address, uint16, uint256, uint256, bytes)">
    **Mutability:** `nonpayable`. The authorizer must still be the owner or a live root TRADE/ADMIN signer. Check the next child sequence, root epoch, deadline, and AccountCore signature domain.

    | Parameter | Solidity type |
    | - | - |
    | `rootOwner` | `address` |
    | `authorizer` | `address` |
    | `subaccountSeq` | `uint16` |
    | `authNonce` | `uint256` |
    | `deadline` | `uint256` |
    | `signature` | `bytes` |

    **Returns:** `uint40 subaccountId`.
  </Accordion>

  <Accordion title="authorizeAccountSigner(address, address, uint32, uint64)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `account` | `address` |
    | `signer` | `address` |
    | `permissions` | `uint32` |
    | `expiry` | `uint64` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="authorizeAccountSignerBySig(address, address, address, uint32, uint64, uint256, uint256, bytes)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `account` | `address` |
    | `authorizer` | `address` |
    | `signer` | `address` |
    | `permissions` | `uint32` |
    | `expiry` | `uint64` |
    | `nonce` | `uint256` |
    | `deadline` | `uint256` |
    | `signature` | `bytes` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="revokeAccountSigner(address, address)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `account` | `address` |
    | `signer` | `address` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="revokeAccountSignerBySig(address, address, address, uint256, uint256, bytes)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `account` | `address` |
    | `authorizer` | `address` |
    | `signer` | `address` |
    | `nonce` | `uint256` |
    | `deadline` | `uint256` |
    | `signature` | `bytes` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="accountAuthorizationEpoch(uint40)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |

    **Returns:** `uint256`.
  </Accordion>

  <Accordion title="accountSignerAuthorizationNonces(address)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `rootOwner` | `address` |

    **Returns:** `uint256`.
  </Accordion>

  <Accordion title="isAuthorizedAccountSignerById(uint40, address, uint32)">
    **Mutability:** `view`. Check TRADE on the target ID. Delegated non-trading checks must use the root ID; a child query masks out those roles.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |
    | `signer` | `address` |
    | `permission` | `uint32` |

    **Returns:** `bool`.
  </Accordion>

  <Accordion title="approveBuilder(address, uint32, uint64)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `builder` | `address` |
    | `maxFeePps` | `uint32` |
    | `expiry` | `uint64` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="revokeBuilder(address)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `builder` | `address` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="getBuilderApproval(address, address)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `rootAccount` | `address` |
    | `builder` | `address` |

    **Returns:** `(uint32 maxFeePps, uint64 expiry, bool active)`.
  </Accordion>

  <Accordion title="effectiveSpotMakerFeePps(uint40, uint256)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |
    | `marketMakerFeePps` | `uint256` |

    **Returns:** `uint32`.
  </Accordion>

  <Accordion title="effectiveSpotTakerFeePps(uint40, uint256)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |
    | `marketTakerFeePps` | `uint256` |

    **Returns:** `uint32`.
  </Accordion>

  <Accordion title="getAccountFeeTierById(uint40)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |

    **Returns:** `(uint32 makerFeePps, uint32 takerFeePps, bool active) tier`.
  </Accordion>

  <Accordion title="getBuilderReferralById(uint40)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `accountId` | `uint40` |

    **Returns:** `(address builder, uint32 makerFeePps, uint32 takerFeePps, uint64 expiry) referral`, `bool active`.
  </Accordion>

  <Accordion title="getBuilderReferralTier(address)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `builder` | `address` |

    **Returns:** `(uint32 makerFeePps, uint32 takerFeePps, uint64 expiry, bool active)`.
  </Accordion>

  <Accordion title="enrollBuilderReferralBySig(address, address, uint32, uint32, uint64, bytes32, uint256, bytes)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `rootAccount` | `address` |
    | `builder` | `address` |
    | `makerFeePps_` | `uint32` |
    | `takerFeePps_` | `uint32` |
    | `referralExpiry` | `uint64` |
    | `nonce` | `bytes32` |
    | `deadline` | `uint256` |
    | `signature` | `bytes` |

    **Returns:** `uint40 rootAccountId`.
  </Accordion>

  <Accordion title="revokeBuilderReferral(address)">
    **Mutability:** `nonpayable`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `rootAccount` | `address` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="approvedWithdrawalNonces(address)">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    | Parameter | Solidity type |
    | - | - |
    | `argument0` | `address` |

    **Returns:** `uint256`.
  </Accordion>

  <Accordion title="withdrawalAuthorityEpoch()">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    No parameters.

    **Returns:** `uint64`.
  </Accordion>

  <Accordion title="withdrawalLimiter()">
    **Mutability:** `view`. Use the account, permission, and execution rules described above and in the linked SDK guide.

    No parameters.

    **Returns:** `address`.
  </Accordion>

  <Accordion title="fulfillApprovedWithdrawal(tuple, bytes)">
    **Mutability:** `nonpayable`. Only the configured withdrawal authority submits this call. It requires a root-owner signature; bypasses ordinary capacity but preserves prices, freezes, balance and transfer checks.

    | Parameter | Solidity type |
    | - | - |
    | `withdrawal` | `(address account, address token, address recipient, uint256 amount, uint256 nonce, uint256 deadline, uint64 authorityEpoch)` |
    | `ownerSignature` | `bytes` |

    **Returns:** No Solidity return value.
  </Accordion>

  <Accordion title="invalidateApprovedWithdrawalNonce(address, uint256)">
    **Mutability:** `nonpayable`. Invalidates older approved-payout signatures. This nonce is distinct from the signer authorization epoch.

    | Parameter | Solidity type |
    | - | - |
    | `account` | `address` |
    | `nextNonce` | `uint256` |

    **Returns:** No Solidity return value.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.