# API reference

Complete reference for all public/external functions, events, and error codes across the Accumulator contract system.

## ShellAccumulatorRootUSDC

Source: `contracts/accumulator/ShellAccumulatorRootUSDC.sol` · Version: 1.0.2\
\&#xNAN;*It will be available after the next node release*

### Entry points

#### `buyShellFor(address buyer)`

```solidity
function buyShellFor(address buyer) public
```

Accepts ECC USDC attached to the message and processes a buy on behalf of `buyer`. Used by Exchange to forward purchases. Does **not** check for multi-currency messages — only verifies ECC USDC is present.

#### `claimUSDC(uint16 D, uint64 orderId, address seller)`

```solidity
function claimUSDC(uint16 D, uint64 orderId, address seller) public
```

Called by a SellOrderLot to claim its USDC payout. Verifies caller address deterministically, checks the order is sold (`orderId <= soldPrefix[D]`), sends ECC USDC to `seller`, then calls `onReceiveUSDC` on the lot.

### Admin

#### `setPubkey(uint256 pubkey)`

```solidity
function setPubkey(uint256 pubkey) public onlyOwnerPubkey accept
```

Replaces the owner public key. Only callable by the current owner (verified via `msg.pubkey()`).

### Getters

#### `getQueueState(uint16 D)`

```solidity
function getQueueState(uint16 D) external view
    returns (uint64 nextId, uint64 available, uint64 soldPrefix, uint64 owedCount)
```

Returns the FIFO queue state for denomination `D` (1, 10, 100, or 1000).

* `nextId` — next order ID to assign (1-based)
* `available` — lots waiting to be matched by a buyer
* `soldPrefix` — contiguous count of sold lots from the start
* `owedCount` — sold lots that haven't been claimed yet

#### `getDetails()`

```solidity
function getDetails() external view
    returns (uint256 ownerPubkey, uint128 sellerShellPool, uint128 usdcBalance, uint128 owedTotal)
```

Returns high-level contract state.

* `sellerShellPool` — total ECC SHELL held from seller deposits (nanoSHELL)
* `usdcBalance` — total ECC USDC tracked by the contract (microUSDC)
* `owedTotal` — total USDC owed to sellers awaiting claim (microUSDC)

#### `getSellOrderAddress(uint16 D, uint64 orderId)`

```solidity
function getSellOrderAddress(uint16 D, uint64 orderId) external view
    returns (address sellOrderAddr)
```

Computes the deterministic address of a lot contract given its denomination and order ID. Useful for off-chain address resolution without deploying.

#### `owedUsdcTotal()`

```solidity
function owedUsdcTotal() external view returns (uint128)
```

Returns total USDC owed to all sellers across all denominations (microUSDC).

#### `getSellerShellPool()`

```solidity
function getSellerShellPool() external view returns (uint128)
```

Returns total ECC SHELL in the seller pool (nanoSHELL).

#### `getUsdcBalance()`

```solidity
function getUsdcBalance() external view returns (uint128)
```

Returns the USDC balance tracked by the contract (microUSDC). This is the accounting balance, not necessarily the on-chain ECC balance.

#### `getNacklInfo()`

```solidity
function getNacklInfo() external view
    returns (uint128 supply, uint128 burned, uint32 unixstart)
```

Returns NACKL emission state.

* `supply` — current `M(t)` from the emission curve (nanoNACKL)
* `burned` — total NACKL burned via `redeemNACKL` to date (nanoNACKL)
* `unixstart` — emission start timestamp (Unix seconds)

The effective circulating supply is `supply - burned`.

#### `getVersion()`

```solidity
function getVersion() external pure returns (string version, string name)
```

Returns `("1.0.2", "ShellAccumulatorRootUSDC")`.

***

## ShellSellOrderLot

Source: `contracts/accumulator/ShellSellOrderLot.sol` · Version: 1.0.2\
\&#xNAN;*It will be available after the next node release*

### Entry points

#### `claim()`

```solidity
function claim() public
```

Initiates USDC payout claim. Sets `_claimed = true` and calls `Root.claimUSDC(denom, orderId, owner)`. If the root rejects (order not yet sold), the bounced message resets `_claimed = false` via `onBounce`.

Can be called by anyone (no `msg.sender` check), but the payout always goes to `_owner` (the original seller).

#### `onReceiveUSDC(uint128 amount)`

```solidity
function onReceiveUSDC(uint128 amount) public senderIs(_root) accept
```

Callback from the Root confirming payout was sent. Verifies `amount == _denom * USDC_DECIMALS_FACTOR`, emits `OrderDestroyed`, and self-destructs.

### Getters

#### `getDetails()`

```solidity
function getDetails() external view
    returns (address root, address owner, uint16 denom, uint64 orderId, bool claimed)
```

Returns all lot metadata.

* `root` — parent Accumulator address
* `owner` — seller address (receives USDC payout)
* `denom` — lot denomination (1, 10, 100, 1000)
* `orderId` — FIFO position within the denomination queue
* `claimed` — `true` if `claim()` was called and is pending or completed

#### `getVersion()`

```solidity
function getVersion() external pure returns (string version, string name)
```

Returns `("1.0.2", "ShellSellOrderLot")`.

***

## Exchange

Source: `contracts/exchange/Exchange.sol` · Version: 1.0.4\
\&#xNAN;*It will be available after the next node release*

### Entry points

#### `onTransferReceived(address from, address to, uint128 value, uint128 balance)`

```solidity
function onTransferReceived(address from, address, uint128 value, uint128) external override
```

ISubscriber callback from the Exchange's TIP-3 USDC wallet. Mints equivalent ECC USDC and sends it to `from` (the depositor). Only callable by `_usdcWallet`.

#### `mintAndSend(address recipient, uint128 value, uint64 nonce)`

```solidity
function mintAndSend(address recipient, uint128 value, uint64 nonce) public onlyOwnerPubkey accept
```

Admin-only. Mints ECC USDC and sends to `recipient`. Requires `nonce == _mintNonce + 1`.

#### `mintAndSendAccumulator(address buyer, uint128 value, uint64 nonce)`

```solidity
function mintAndSendAccumulator(address buyer, uint128 value, uint64 nonce) public onlyOwnerPubkey accept
```

Admin-only. Mints ECC USDC and calls `Accumulator.buyShellFor(buyer)` with the minted USDC attached. Requires whole USDC units and `nonce == _mintAccumulatorNonce + 1`. Uses separate nonce space from `mintAndSend`.

### Admin

#### `setPubkey(uint256 pubkey)`

```solidity
function setPubkey(uint256 pubkey) public onlyOwnerPubkey accept
```

Replaces the owner public key.

#### `triggerTransaction(address txAddr)`

```solidity
function triggerTransaction(address txAddr) public view onlyOwnerPubkey accept
```

Sends 1 vmshell to `txAddr`. Used to trigger Transaction contracts for wallet setup (e.g., `SET_SUBSCRIBER_TYPE`).

### Getters

#### `getUsdcWallet()`

```solidity
function getUsdcWallet() external view returns (address)
```

Returns the TIP-3 USDC TokenWallet address used for the bridge.

#### `getOwnerPubkey()`

```solidity
function getOwnerPubkey() external view returns (uint256)
```

Returns the current owner public key.

#### `getTotalMinted()`

```solidity
function getTotalMinted() external view returns (uint128)
```

Returns total ECC USDC minted by this contract across all methods (microUSDC).

#### `getNonces()`

```solidity
function getNonces() external view returns (uint64 mintNonce, uint64 mintAccumulatorNonce)
```

Returns current nonces for both mint paths. The next valid nonce for each path is `current + 1`.

#### `getVersion()`

```solidity
function getVersion() external pure returns (string version, string name)
```

Returns `("1.0.4", "Exchange")`.

***

## AccumulatorLib

Source: `contracts/accumulator/libraries/AccumulatorLib.sol` · Version: 1.0.2\
\&#xNAN;*It will be available after the next node release*

#### `calculateSellOrderAddress(TvmCell code, address root, uint16 denom, uint64 orderId)`

```solidity
function calculateSellOrderAddress(TvmCell code, address root, uint16 denom, uint64 orderId)
    public returns (address)
```

Computes the deterministic address of a SellOrderLot. The address is `makeAddrStd(0, hash(stateInit))`.

#### `composeSellOrderStateInit(TvmCell code, address root, uint16 denom, uint64 orderId)`

```solidity
function composeSellOrderStateInit(TvmCell code, address root, uint16 denom, uint64 orderId)
    public returns (TvmCell)
```

Builds the full stateInit for a lot: salted code + static variables `_denom` and `_orderId`.

#### `buildSellOrderCode(TvmCell originalCode, address root)`

```solidity
function buildSellOrderCode(TvmCell originalCode, address root)
    public returns (TvmCell)
```

Salts the lot code with `abi.encode(versionLib, root)`. This binds the lot to a specific Root contract and library version.

***

## Events

All events are emitted to **external addresses** (directed events) for off-chain subscription. The external address is constructed as `address.makeAddrExtern(eventId, 256)`.

### Root events

| Event              | Ext Addr                   | Fields                                                                               | Emitted when                                                                     |
| ------------------ | -------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
| `SellOrderCreated` | **610** + seller's address | `(address seller, uint16 denom, uint64 orderId, uint128 shellAmount)`                | New lot created. Emitted twice: to addr 610 and to the seller's external address |
| `ShellPurchased`   | **611**                    | `(address buyer, uint128 usdcAmount, uint128 shellFromSellers, uint128 shellMinted)` | Buy completed                                                                    |
| `UsdcClaimed`      | **612**                    | `(uint64 orderId, uint16 denom, address seller, uint128 payout)`                     | Seller claimed USDC                                                              |
| `NacklRedeemed`    | **613**                    | `(address recipient, uint128 burnAmount, uint128 payout)`                            | NACKL burned for USDC                                                            |
| `MatchedOrders`    | **617**                    | `(uint64 lastSold1, uint64 lastSold10, uint64 lastSold100, uint64 lastSold1000)`     | Updated soldPrefix values after a buy                                            |

### Lot events

| Event            | Target   | Fields                                           |
| ---------------- | -------- | ------------------------------------------------ |
| `ClaimInitiated` | internal | `(uint64 orderId, uint16 denom, address owner)`  |
| `OrderDestroyed` | internal | `(uint64 orderId, uint16 denom, uint128 amount)` |

### Exchange events

| Event          | Ext Addr | Fields                               | Emitted when                                                            |
| -------------- | -------- | ------------------------------------ | ----------------------------------------------------------------------- |
| `UsdcMigrated` | **615**  | `(address from, uint128 value)`      | TIP-3 USDC bridged to ECC                                               |
| `UsdcMinted`   | **616**  | `(address recipient, uint128 value)` | Admin-minted ECC USDC (from `mintAndSend` and `mintAndSendAccumulator`) |

***

## Error Codes

### Accumulator errors (Root + SellOrderLot)

| Code | Name                          | Meaning                                                  |
| ---- | ----------------------------- | -------------------------------------------------------- |
| 200  | `ERR_INVALID_DENOM`           | Denomination is not 1, 10, 100, or 1000                  |
| 201  | `ERR_WRONG_SHELL_AMOUNT`      | SHELL amount doesn't divide evenly by SHELL\_PER\_USDC   |
| 202  | `ERR_WRONG_USDC_AMOUNT`       | USDC amount mismatch in onReceiveUSDC or balance check   |
| 203  | `ERR_NOT_WHOLE_USDC`          | USDC amount is not a whole number (not divisible by 10⁶) |
| 204  | `ERR_ZERO_AMOUNT`             | Zero amount supplied                                     |
| 205  | `ERR_ORDER_NOT_SOLD`          | Lot's orderId > soldPrefix (not yet matched)             |
| 206  | `ERR_NO_OWED`                 | No owed claims remaining for this denomination           |
| 207  | `ERR_INVALID_SENDER`          | Caller is not the expected contract                      |
| 208  | `ERR_ALREADY_CLAIMED`         | claim() already called on this lot                       |
| 209  | `ERR_NOT_OWNER`               | msg.pubkey() doesn't match owner                         |
| 210  | `ERR_INSUFFICIENT_REDEEMABLE` | Not enough free reserve for NACKL redemption             |
| 211  | `ERR_WRONG_CODE`              | (reserved)                                               |
| 212  | `ERR_WRONG_ADDRESS`           | Caller address doesn't match deterministic lot address   |
| 213  | `ERR_MULTIPLE_CURRENCIES`     | Message carries more than one ECC currency type          |
| 214  | `ERR_OVERFLOW`                | Amount exceeds uint64 max                                |

### Exchange errors

| Code | Name                 | Meaning                          |
| ---- | -------------------- | -------------------------------- |
| 204  | `ERR_ZERO_AMOUNT`    | Zero value                       |
| 207  | `ERR_INVALID_SENDER` | Caller is not the USDC wallet    |
| 209  | `ERR_NOT_OWNER`      | msg.pubkey() doesn't match owner |
| 213  | `ERR_NOT_WHOLE_USDC` | Value not divisible by 10⁶       |
| 214  | `ERR_OVERFLOW`       | Value exceeds uint64 max         |
| 215  | `ERR_INVALID_NONCE`  | Nonce is not current + 1         |

{% hint style="info" %}
Error code 213 means different things in different contracts: `ERR_MULTIPLE_CURRENCIES` in the Accumulator vs `ERR_NOT_WHOLE_USDC` in the Exchange. When debugging failed transactions, check which contract emitted the error.
{% endhint %}

***

## Constants

### Token IDs and decimals

| Constant                | Value                       | Used in        |
| ----------------------- | --------------------------- | -------------- |
| `NACKL_ECC_ID`          | 1                           | Root           |
| `SHELL_ECC_ID`          | 2                           | Root           |
| `USDC_ECC_ID`           | 3                           | Root, Exchange |
| `SHELL_DECIMALS_FACTOR` | 1,000,000,000 (10⁹)         | Root           |
| `USDC_DECIMALS_FACTOR`  | 1,000,000 (10⁶)             | Root, Exchange |
| `SHELL_PER_USDC`        | 100,000,000,000 (100 × 10⁹) | Root           |

### NACKL emission

| Constant         | Value                      | Meaning                        |
| ---------------- | -------------------------- | ------------------------------ |
| `NACKL_T`        | 10,400,000,000,000,000,000 | Max supply cap (nanoNACKL)     |
| `NACKL_T_KM`     | 10,400,104,000,000,000,000 | T × (1 + K\_M), K\_M = 0.00001 |
| `NACKL_U_M_FP18` | 5,756,467,732              | Growth rate × 10¹⁸             |
| `FP18`           | 10¹⁸                       | Fixed-point scaling factor     |
| `INV_E_FP18`     | 367,879,441,171,442,322    | exp(-1) × 10¹⁸                 |

### Denominations

```
DENOM_1    = 1
DENOM_10   = 10
DENOM_100  = 100
DENOM_1000 = 1000
```


---

# Agent Instructions: 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:

```
GET https://dev.ackinacki.com/accumulator-contract-system/api-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
