diff --git a/reference/atomicassets/actions.md b/reference/atomicassets/actions.md index 45971a7..591de73 100644 --- a/reference/atomicassets/actions.md +++ b/reference/atomicassets/actions.md @@ -1,7 +1,7 @@ --- scope: Complete action reference for the `atomicassets` contract - admin, collections, schemas, templates, assets, RAM-payer reassignment, transfers, and offers depends-on: [reference/atomicassets/structure.md, reference/atomicassets/tables.md] -key-modules: ["atomicassets-contract (v2.0.0-rc4): src/atomicassets.cpp, include/atomicassets.hpp"] +key-modules: ["atomicassets-contract (v2.0.0-rc4): src/atomicassets.cpp, include/atomicassets.hpp", "AntelopeIO/leap (v5.0.3): chain RAM-billing constants"] --- # AtomicAssets actions @@ -410,9 +410,9 @@ Source: `include/atomicassets.hpp:303-308`, `src/atomicassets.cpp:1535-1547` Required authorization: `from`. -Notifies `from` and `to` directly via `require_recipient`, then calls `internal_transfer`, which: requires `to` to exist and differ from `from`; requires every asset to currently belong to `from` and, if templated, to have `transferable = true`; and, if this is the first asset `to` has ever held (an empty scope), makes `from` pay for the new scope's RAM by emplacing and immediately erasing a placeholder row (so the action fails outright if `from` cannot cover that RAM). Sends one `logtransfer` per distinct collection touched by the batch (grouped by `std::map` key order, not caller-supplied order), each of which fans out to that collection's `notify_accounts`. +Notifies `from` and `to` directly via `require_recipient`, then calls `internal_transfer`, which: requires `to` to exist and differ from `from`; requires every asset to currently belong to `from` and, if templated, to have `transferable = true`; and, if this is the first asset `to` has ever held (an empty scope), makes `from` pay for the new scope's RAM by emplacing and immediately erasing a placeholder row (so the action fails outright if `from` cannot cover that RAM); that charge is exactly 112 bytes, the billable size the chain gives a `table_id_object`, the record that carries one table scope, and it stays with `from` while the scope exists. Sends one `logtransfer` per distinct collection touched by the batch (grouped by `std::map` key order, not caller-supplied order), each of which fans out to that collection's `notify_accounts`. -Source: `include/atomicassets.hpp:30-35`, `src/atomicassets.cpp:76-86`, `src/atomicassets.cpp:1665-1761` (`internal_transfer`) +Source: `include/atomicassets.hpp:30-35`, `src/atomicassets.cpp:76-86`, `src/atomicassets.cpp:1665-1761` (`internal_transfer`); for the 112-byte figure, `AntelopeIO/leap` at `v5.0.3`: `libraries/chain/include/eosio/chain/config.hpp:108,140,146` and `libraries/chain/include/eosio/chain/contract_table_objects.hpp:244-247` (`billable_size_v` = align_up(44 + 2x32, 16) = 112), charged at `libraries/chain/apply_context.cpp:691`; live WAX mainnet read via `wax.greymass.com` `POST /v1/history/get_transaction`, tx `1ec40244151f86b361f9fa18de6ed7bb1413608792141538e0de531a53c55393`, whose `account_ram_deltas` bill the sender exactly +112 ### createoffer diff --git a/reference/atomicmarket/ram.md b/reference/atomicmarket/ram.md index 952b038..40f04ce 100644 --- a/reference/atomicmarket/ram.md +++ b/reference/atomicmarket/ram.md @@ -1,7 +1,7 @@ --- scope: Who pays RAM for each `atomicmarket` table row, the voluntary pay*ram re-homing actions, and sizing implications for a high-volume marketplace or dapp depends-on: [reference/atomicmarket/tables.md] -key-modules: ["atomicmarket-contract (v2.0.0-rc2): src/atomicmarket.cpp, include/atomicmarket.hpp"] +key-modules: ["atomicmarket-contract (v2.0.0-rc2): src/atomicmarket.cpp, include/atomicmarket.hpp", "AntelopeIO/leap (v5.0.3): chain RAM-billing constants"] --- # AtomicMarket RAM @@ -10,9 +10,9 @@ Who pays the RAM for each `atomicmarket` table row, the voluntary `pay*ram` acti ## The contract pays RAM for every balances row -`internal_add_balance`, the only function that creates or grows a `balances` row, always uses `get_self()` as the RAM payer, never the account the balance belongs to. This is true regardless of why the balance exists: a marketplace's maker/taker fee cut, a royalty recipient's split payout, a token deposit, or a seller's proceeds all land in a `balances` row paid for by the `atomicmarket` contract account itself. There is one row per owner (scope `get_self()`, primary key `owner.value`), holding a `vector` of per-symbol quantities rather than one row per token type, so a single account accruing balances in several token symbols still only costs one row's worth of base RAM. `internal_decrease_balance` erases the row entirely once its last quantity reaches zero (and merely shrinks the quantities vector if other symbols remain), so a fully-withdrawn balance gives its RAM back rather than leaving an empty row behind. +`internal_add_balance`, the only function that creates or grows a `balances` row, always uses `get_self()` as the RAM payer, never the account the balance belongs to. This is true regardless of why the balance exists: a marketplace's maker/taker fee cut, a royalty recipient's split payout, a token deposit, or a seller's proceeds all land in a `balances` row paid for by the `atomicmarket` contract account itself. There is one row per owner (scope `get_self()`, primary key `owner.value`), holding a `vector` of per-symbol quantities rather than one row per token type, so a single account accruing balances in several token symbols still only costs one row's worth of base RAM. `internal_decrease_balance` erases the row entirely once its last quantity reaches zero (and merely shrinks the quantities vector if other symbols remain), so a fully-withdrawn balance gives its RAM back rather than leaving an empty row behind. A row costs 121 + 16 x N bytes for any N up to 127, N being the number of distinct token symbols in `quantities`: the chain's fixed 112-byte row overhead plus the packed payload (the 8-byte `owner`, a 1-byte vector length prefix, and 16 bytes per `asset`). At 128 symbols the length prefix takes a second byte and the constant becomes 122, which no live token configuration approaches. -Source: `src/atomicmarket.cpp:2993-3026` (`internal_add_balance`), `src/atomicmarket.cpp:3034-3070` (`internal_decrease_balance`), `include/atomicmarket.hpp:519-526` (`balances_s`) +Source: `src/atomicmarket.cpp:2993-3026` (`internal_add_balance`), `src/atomicmarket.cpp:3034-3070` (`internal_decrease_balance`), `include/atomicmarket.hpp:519-526` (`balances_s`); for the byte cost, `AntelopeIO/leap` at `v5.0.3`: `libraries/chain/include/eosio/chain/contract_table_objects.hpp:249-253` (`billable_size_v` = 112) and `libraries/chain/apply_context.cpp:813` (`db_store_i64` bills that overhead plus the packed row size); live WAX mainnet reads via `wax.greymass.com` `POST /v1/history/get_transaction`: tx `cabbeb2b2760c4d0e3a70363e902362b468775ad98ef970d71e1d2ad1a4788c3` (a memo-`deposit` transfer billing `atomicmarket` exactly +137, which is 121 + 16 for one symbol) and two corroborating settlement transactions showing the same +137/-137 pair ## Sellers and buyers pay RAM for their own listing rows by default diff --git a/validation-log.md b/validation-log.md index 2bec346..17d535f 100644 --- a/validation-log.md +++ b/validation-log.md @@ -19,6 +19,7 @@ This log traces how every fact in `reference/` and `guides/` was checked before - `@wharfkit/antelope` at `1.1.1` - `@wharfkit/session` at `1.6.1`, with `@wharfkit/common` at `1.5.0` and `@wharfkit/wallet-plugin-privatekey` at `1.1.0` - `@atomichub/vert` at `2.2.0`, commit `a8a4160` +- `AntelopeIO/leap` at `v5.0.3` (chain RAM billing: the billable-size constants and the call sites that charge them) A page's `key-modules` frontmatter names the specific baseline(s) it draws from; entries below carry the same pin unless noted otherwise. @@ -38,7 +39,7 @@ WAX mainnet still runs the V1 `atomicassets` and `atomicmarket` contracts (confi | `reference/sdk/atomicassets.md` | `atomicassets-sdk` (`v2.1.1`, `5c70c62`): `src/index.ts`, `src/API/Explorer/index.ts`, `src/API/Rpc/index.ts`, `src/Actions/Generator.ts`, `src/Serialization/index.ts`, `src/Schema/index.ts`, `src/Networks.ts`, `package.json`, `test/explorer-url.test.ts`; live reads of `wax.api.atomicassets.io` | both | The getter-and-route table, the serialization split, action shapes, and error types are read from the 2.1.1 source, each section citing file and line. Source-read at 2.1.1: the lazy `action` getter (construction starts no request), percent-encoding of path segments and of both sides of every query pair, the empty-and-dot-segment guard added in 2.1.1 (its two throw messages, the sixteen guarded getters, the plain `Error` rather than an `ApiError`, and that nothing is sent, all read from `encodeSegment` and the paired test), the numeric ABI-type guards and the fields they cover, the `backasset` and `tokens_to_back` deprecation, and the one-object-versus-array asymmetry against the market builder. The `getTemplateStats` row now reads `(collection, id)`, correcting a `name` the 2.1.1 signature renamed. ExplorerApi reads, a serialization round-trip against a live schema format, the 8-arg `mintasset` output, and the network factories were executed against the built SDK at the earlier 2.0.0 pin and the affected signatures re-read at 2.1.1. The zero-runtime-deps and `sideEffects` facts are from `package.json`. | | `reference/sdk/atomicmarket.md` | `atomicmarket-sdk` (`v2.4.1`, `437300b`): `src/index.ts`, `src/API/Explorer/index.ts`, `src/API/Explorer/Objects.ts`, `src/API/Explorer/Enums.ts`, `src/API/Explorer/Params.ts`, `src/Actions/Generator.ts`, `src/Actions/Delphi.ts`, `src/Actions/Symbols.ts`, `src/Tables.ts`, `src/Networks.ts`, `package.json`, `test/path-segments.test.ts`; live reads of `wax.api.atomicassets.io` and `test.wax.api.atomicassets.io` | both | The read-surface table, the 31-method action surface (26 actions plus five composers), the composer contracts, and the delphi settlement math are read from the 2.4.1 source, each section citing file and line. Source-read at 2.4.1: the empty-and-dot-segment guard (its two throw messages, the thirteen guarded readers, the plain `Error` that travels out of `getRoyaltyConfig` because only a 416 `ApiError` maps to `null`), and the payout filter surfaces `RoyaltyPayoutApiParams` and `RoyaltyAccountApiParams`. Live-chain: `/atomicmarket/v2/sales` and its `_count` answer 200 on WAX mainnet; the mainnet royalty route answers HTTP 416 with `Royalty config not found`, which corrects the 404 this page previously claimed and inverts the guard advice, since `getRoyaltyConfig` maps 416 to `null`; the WAX testnet royalty reads and the testnet `getConfig` sample (contract `version: 2.0.0`, the `waxpusd` pair) were read live, and mainnet `getConfig` reads `1.3.3`. Live-chain for the 2.4.0 payout ledger: the testnet `/royalties/payouts`, `/payouts/_count`, and `/accounts/{account}` routes answer 200 with rows matching `IRoyaltyPayout` and `IRoyaltyAccountTotal` field for field, the `_count` value arrives as the string `"20"`, the sampled rows confirm the category-to-linkage rule, and the same three routes on WAX mainnet answer 200 with an empty list and a zero count, which is the V1-chain case. The added `market_contract`, `collection_name`, timestamp, and `lookup_hash` fields on the config and rule rows are live-read from the testnet royalty routes as well as declared in `Objects.ts`. The worked `deriveSettlementAmount` figures are computed from the pinned formula against that live pair, not observed on chain. | | `reference/atomicassets-api.md` | `atomicassets-api`: `package.json`, `src/api/server.ts` | source-read | Cites repo metadata and the documentation-server source; no live probe cited. | -| `reference/atomicassets/actions.md` | `atomicassets-contract` (v2.0.0-rc4): `src/atomicassets.cpp`, `include/atomicassets.hpp` | source-read | Every action cites specific header and implementation line ranges. | +| `reference/atomicassets/actions.md` | `atomicassets-contract` (v2.0.0-rc4): `src/atomicassets.cpp`, `include/atomicassets.hpp`; `AntelopeIO/leap` (v5.0.3) billing constants; live WAX mainnet `get_transaction` read | both | Every action cites specific header and implementation line ranges. The 112-byte new-scope transfer charge is checked both ways: computed from the pinned leap billing constants and observed as the sender's `account_ram_deltas` entry in a live WAX mainnet transfer. | | `reference/atomicassets/backing-tokens.md` | `atomicassets-contract` (v2.0.0-rc4): `src/atomicassets.cpp`, `include/atomicassets.hpp` | source-read | Cites `announcedepo`, `withdraw`, `addconftoken`, `burnasset`, and the V2 `backasset` abort by line range. | | `reference/atomicassets/custom-types.md` | `atomicassets-contract` (v2.0.0-rc4): `include/atomicdata.hpp`, `include/checkformat.hpp`, `src/atomicassets.cpp` | source-read | Includes one negative check (`setschematyp` confirmed absent from the V1 source tree) alongside the V2 citations. | | `reference/atomicassets/data-precedence.md` | `atomicassets-contract` (v2.0.0-rc4): `src/atomicassets.cpp`, `include/atomicdata.hpp` | source-read | One fact is cross-checked against `atomicassets-api src/api/namespaces/atomicassets/format.ts` in addition to contract source. | @@ -50,7 +51,7 @@ WAX mainnet still runs the V1 `atomicassets` and `atomicmarket` contracts (confi | `reference/atomicmarket/actions.md` | `atomicmarket-contract` (v2.0.0-rc2): `src/atomicmarket.cpp`, `include/atomicmarket.hpp` | source-read | Every action cites header and implementation line ranges. | | `reference/atomicmarket/fees-and-royalties.md` | `atomicmarket-contract` (v2.0.0-rc2): `src/atomicmarket.cpp`, `include/atomicmarket.hpp`; live wax-testnet sale settlement | both | Cites `internal_payout_sale`, fee-bound actions, and the royalty split/log actions by line range. The four-layer fee stack, the founders/template/attribute split summing exactly to the collection fee, the standing 2% WAX bonus fee, and the `/sales/{id}/logs` payout read are live-chain-confirmed by a cold-validation trade run on wax-testnet. | | `reference/atomicmarket/marketplaces.md` | `atomicmarket-contract` (v2.0.0-rc2): `src/atomicmarket.cpp`, `include/atomicmarket.hpp` | source-read | Cites `regmarket`, `is_valid_marketplace`, and the maker/taker crediting logic inside `internal_payout_sale`. | -| `reference/atomicmarket/ram.md` | `atomicmarket-contract` (v2.0.0-rc2): `src/atomicmarket.cpp`, `include/atomicmarket.hpp` | source-read | Cites the internal balance helpers and each `pay*ram` action by line range. | +| `reference/atomicmarket/ram.md` | `atomicmarket-contract` (v2.0.0-rc2): `src/atomicmarket.cpp`, `include/atomicmarket.hpp`; `AntelopeIO/leap` (v5.0.3) billing constants; live WAX mainnet `get_transaction` reads | both | Cites the internal balance helpers and each `pay*ram` action by line range. The 121 + 16N balances-row byte cost, which holds for any symbol count up to 127, is checked both ways: computed from the pinned leap billing constants plus the packed row shape, and observed at exactly 137 bytes (N=1) in three live WAX mainnet deposit-and-settlement transactions. | | `reference/atomicmarket/tables.md` | `atomicmarket-contract` (v2.0.0-rc2): `include/atomicmarket.hpp` | source-read | One table per section, each with its own header line-range citation. | | `reference/atomicmarket/v2-changes.md` | `atomicmarket-contract` (v2.0.0-rc2): `src/atomicmarket.cpp` | source-read | The defensive-guards section has an explicit `Source:` line. The "large integers serialize as strings" section describes live nodeos JSON-serialization behavior and carries no dedicated citation in this page; it is consistent with, and narrower than, the live-chain uint64 facts in `guides/querying-the-api.md`. | | `reference/chain.md` | Live `nodeos`/WAX RPC behavior (`/v1/chain/get_account`); nodeos `chain_plugin.cpp` referenced for the error-message format | live-chain | No dedicated `Source:` line in this page. The error code and HTTP behavior are a live-RPC fact; the page also names the nodeos source file that emits the message text, which is not independently re-verified here. | @@ -70,7 +71,7 @@ WAX mainnet still runs the V1 `atomicassets` and `atomicmarket` contracts (confi ## Tier distribution -22 source-read, 1 live-chain, 14 both. 37 pages total. +20 source-read, 1 live-chain, 16 both. 37 pages total. ## Pages with an ambiguous tier signal