diff --git a/src/pages/guide/issuance/create-a-stablecoin.mdx b/src/pages/guide/issuance/create-a-stablecoin.mdx index 880f58d5..1a35aa8a 100644 --- a/src/pages/guide/issuance/create-a-stablecoin.mdx +++ b/src/pages/guide/issuance/create-a-stablecoin.mdx @@ -15,10 +15,6 @@ Create your own stablecoin on Tempo using the [TIP-20 token standard](/protocol/ TIP-20 tokens are designed specifically for payments with built-in compliance features, role-based permissions, and integration with Tempo's payment infrastructure. -:::info[Coming with T5] -After the [T5 network upgrade](/protocol/upgrades/t5), the TIP-20 factory exposes a new 7-arg `createToken` overload that accepts an on-chain `logoURI` at creation ([TIP-1026](https://tips.sh/1026)). Wallets and explorers can read the icon directly from the token contract via `logoURI()`, without going through the [tokenlist registry](/quickstart/tokenlist). The previous `createToken` overload is unchanged. Per [TIP-1026's recommended formats](https://tips.sh/1026#recommended-formats), use a square, single-frame rasterized image (PNG or WebP) for `logoURI`. SVG is allowed by the scheme allowlist but not recommended. See the [Optional logoURI in TIP-20 section of the T5 page](/protocol/upgrades/t5#optional-logouri-in-tip-20-tip-1026) for the full surface area. -::: - ## Demo By the end of this guide, you will be able to create a stablecoin on Tempo. @@ -154,6 +150,8 @@ Now that we have some input fields, we need to add some logic to handle the subm After this step, your users will be able to create a stablecoin by clicking the "Create" button! +Tokens can also carry an optional on-chain `logoURI` ([TIP-1026](https://tips.sh/1026)) that wallets and explorers read directly from the token contract. It's set on the token contract and is independent of this creation flow; for the recommended format, use a square, rasterized PNG or WebP (max 256 bytes; `https`, `http`, `ipfs`, or `data` scheme). + :::warning The `currency` field is **immutable** after token creation and affects fee payment eligibility, DEX routing, and quote token pairing. See [Currency Declaration](/protocol/tip20/overview#currency-declaration) for guidelines on choosing the right value. **Only `USD` stablecoins can be used to pay transaction fees on Tempo.** ::: diff --git a/src/pages/guide/issuance/manage-stablecoin.mdx b/src/pages/guide/issuance/manage-stablecoin.mdx index cd165200..2ca43443 100644 --- a/src/pages/guide/issuance/manage-stablecoin.mdx +++ b/src/pages/guide/issuance/manage-stablecoin.mdx @@ -21,10 +21,6 @@ import { Cards, Card } from 'vocs' Configure your stablecoin's permissions, supply limits, and compliance policies after deployment. This guide covers granting roles to manage token operations, setting supply caps, configuring transfer policies, and controlling token transfers through pause/unpause functionality. -:::info[Coming with T5] -After the [T5 network upgrade](/protocol/upgrades/t5), an admin holding `DEFAULT_ADMIN_ROLE` can update the on-chain `logoURI` field on any TIP-20 via `setLogoURI(string newLogoURI)` ([TIP-1026](https://tips.sh/1026)). Wallets and explorers can read the icon directly from the token contract via `logoURI()`. Per [TIP-1026's recommended formats](https://tips.sh/1026#recommended-formats), use a square, single-frame rasterized image (PNG or WebP) for `logoURI`. SVG is allowed by the scheme allowlist but not recommended. See the [Optional logoURI in TIP-20 section of the T5 page](/protocol/upgrades/t5#optional-logouri-in-tip-20-tip-1026) for the full surface area. -::: - TIP-20 tokens use a role-based access control system that allows you to delegate different administrative functions to different addresses. For detailed information about the role system, see the [TIP-20 specification](/protocol/tip20/spec#role-based-access-control). ## Steps @@ -294,6 +290,10 @@ export const config = createConfig({ ## Recipes +### Set the Token Logo + +Set or update the token's on-chain `logoURI` so wallets and explorers can read the icon directly from the token contract via `logoURI()`. This requires the **`DEFAULT_ADMIN_ROLE`** and is done by calling `setLogoURI(string newLogoURI)` on the token ([TIP-1026](https://tips.sh/1026)). For the recommended format, use a square, rasterized PNG or WebP (max 256 bytes; `https`, `http`, `ipfs`, or `data` scheme). + ### Set Supply Cap Limit the maximum total supply of your token. Setting supply caps requires the **`DEFAULT_ADMIN_ROLE`**. The new cap cannot be less than the current total supply. diff --git a/src/pages/guide/issuance/use-for-fees.mdx b/src/pages/guide/issuance/use-for-fees.mdx index 7f238311..f2150e7f 100644 --- a/src/pages/guide/issuance/use-for-fees.mdx +++ b/src/pages/guide/issuance/use-for-fees.mdx @@ -39,15 +39,11 @@ First, create and mint your stablecoin by following the [Create a Stablecoin](/g ### Add fee pool liquidity -:::info[Coming with T5] -After the [T5 network upgrade](/protocol/upgrades/t5), the FeeAMM supports multihop routing ([TIP-1033](https://tips.sh/1033)). Issuers no longer need to provision a pool against every validator payout token — pairing your token against a single liquid quote (e.g., `pathUSD`) is enough, and multihop routing connects it to any validator payout token that has its own `pathUSD` pool. Until T5 activates, the per-validator-token setup described below still applies. -::: - -Before users can pay fees with your token, you need to provide liquidity in the Fee AMM between your token and each of the tokens accepted by validators. +Before users can pay fees with your token, you need to provide liquidity in the Fee AMM between your token and a liquid quote token, or directly against validator payout tokens where you want explicit direct-route coverage. To determine which validator tokens are needed, sample recent blocks and check the miner's preferred fee token using `getValidatorToken` on the FeeManager contract. For example, on Moderato testnet, validators accept fees in pathUSD and AlphaUSD. On mainnet, this token mix is different and subject to change. -Add liquidity to your token's fee pool for each validator token: +Add liquidity to your token's fee pool: :::code-group diff --git a/src/pages/guide/machine-payments/pay-as-you-go.mdx b/src/pages/guide/machine-payments/pay-as-you-go.mdx index 8388695f..d330f72f 100644 --- a/src/pages/guide/machine-payments/pay-as-you-go.mdx +++ b/src/pages/guide/machine-payments/pay-as-you-go.mdx @@ -14,10 +14,6 @@ Build a payment-gated photo gallery API that charges $0.01 per photo using `mppx Unlike [one-time payments](/guide/machine-payments/one-time-payments), sessions open a payment channel once and use off-chain vouchers for each subsequent request — vouchers are processed in pure CPU-bound signature checks, not bottlenecked by blockchain throughput. ::: -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) ships an enshrined `TIP20ChannelReserve` precompile at [`0x4D50500000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x4D50500000000000000000000000000000000000) (ASCII `MPP`) that replaces the application-level escrow contract for new MPP integrations ([TIP-1034](https://tips.sh/1034)). The existing escrow contract continues to work; SDKs that target the precompile additionally save gas thanks to [implicit approvals](/protocol/upgrades/t5#tip-1035-implicit-approvals-list) — the channel can pull TIP-20 tokens without a prior `approve` transaction. New `mppx` releases that target the precompile will be linked under [Compatible SDK releases](/protocol/upgrades/t5#compatible-sdk-releases). -::: - ## How sessions work diff --git a/src/pages/guide/stablecoin-dex/providing-liquidity.mdx b/src/pages/guide/stablecoin-dex/providing-liquidity.mdx index 0399142f..e7f4d16d 100644 --- a/src/pages/guide/stablecoin-dex/providing-liquidity.mdx +++ b/src/pages/guide/stablecoin-dex/providing-liquidity.mdx @@ -308,16 +308,10 @@ console.log('Quote Token:', metadata?.quoteToken) // returns `pathUSD` address ### Flip order -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) changes flip-order behavior in two ways: -- `flipTick == tick` becomes valid ([TIP-1030](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1030.md)) -- A filled flip order keeps the same `orderId` and emits a new `OrderFlipped` event instead of a fresh `OrderPlaced` ([TIP-1056](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1056.md)) - -Until T5 activates, the behavior described below still applies. Developers updating indexers, SDKs, or contract code should see the [T4 → T5 migration appendix](/protocol/exchange/providing-liquidity#t4--t5-migration) on the Providing Liquidity spec page. -::: - Flip orders automatically switch between buy and sell sides when filled, providing continuous liquidity. Use viem's [`dex.placeFlip`](https://viem.sh/tempo/actions/dex.placeFlip) to create a flip order call. +A flip order can re-list on the opposite side at the same tick (`flipTick == tick`), which is useful for pegged or near-1:1 pairs. When it fills, the order keeps the same `orderId` and emits an `OrderFlipped` event instead of a new `OrderPlaced`, so a single flip strategy stays trackable under one ID across its full lifecycle. Indexers, SDKs, and contract code that follow flip orders should treat `OrderFlipped` as the latest active state — see the [flip-order indexing notes](/protocol/exchange/providing-liquidity#flip-order-indexing). + :::code-group ```tsx twoslash [PlaceFlipOrder.tsx] diff --git a/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx b/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx index c2cd79e8..d7ee6b95 100644 --- a/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx +++ b/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx @@ -7,14 +7,12 @@ import { IndexSupplyQuery } from '../../../components/IndexSupplyQuery' # View the Orderbook -Query and inspect the orderbook to see available liquidity, price levels, and individual orders on Tempo's Stablecoin DEX. - -:::info[Coming with T5] -After the [T5 network upgrade](/protocol/upgrades/t5), flip orders keep the same `orderId` when they flip. A fully filled flip order emits `OrderFilled`, then re-enters the book under the same `orderId` with an `OrderFlipped` event instead of a new `OrderPlaced` event. - -The SQL recipes below are pre-T5 examples. They currently treat any full `OrderFilled` as the end of an order and only read active liquidity from `OrderPlaced`, so they will miss flipped orders after T5. Post-T5 indexers should read `OrderFlipped` as the latest active state for that `orderId`, including its new side, tick, and flip tick. See the [T4 → T5 migration appendix](/protocol/exchange/providing-liquidity#t4--t5-migration) for the full action list. +:::warning[Recipes being updated] +These SQL recipes don't yet account for [flip orders](/protocol/exchange/providing-liquidity#flip-order-indexing), which keep the same `orderId` and re-list via `OrderFlipped` when filled — results may omit or misreport flipped orders. Updated queries are in progress. ::: +Query and inspect the orderbook to see available liquidity, price levels, and individual orders on Tempo's Stablecoin DEX. + ## Recommended Approach We recommend using indexed data to query the orderbook for better performance and ease of use. While you can query logs and transactions directly from an RPC node, indexed data providers offer structured SQL interfaces that make complex queries simpler and more efficient. diff --git a/src/pages/guide/use-accounts/authorize-access-keys.mdx b/src/pages/guide/use-accounts/authorize-access-keys.mdx index a88b554c..186bddae 100644 --- a/src/pages/guide/use-accounts/authorize-access-keys.mdx +++ b/src/pages/guide/use-accounts/authorize-access-keys.mdx @@ -15,10 +15,6 @@ import { Tabs, Tab } from 'vocs' Send stablecoin payments using an access key: a secondary signing key that lets you transact without repeated passkey prompts. Access keys can be scoped with spending limits and expiry for security. -:::info[Coming with T5] -After the [T5 network upgrade](/protocol/upgrades/t5), `key_authorization` gains an optional `witness: bytes32` field ([TIP-1053](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1053.md)). "Sign-In with Tempo" style apps can derive a 32-byte witness from their challenge and include it in the access-key authorization, so a single user signature both authorizes the access key and binds to the app's challenge — replacing the current two-prompt flow. No breaking change; existing flows continue to work unchanged. -::: - ## Demo By the end of this guide you will be able to send payments on Tempo using an access key. Notice that no passkey prompt appears when sending a payment. diff --git a/src/pages/protocol/blockspace/payment-lane-specification.mdx b/src/pages/protocol/blockspace/payment-lane-specification.mdx index c2c33d4e..a590b908 100644 --- a/src/pages/protocol/blockspace/payment-lane-specification.mdx +++ b/src/pages/protocol/blockspace/payment-lane-specification.mdx @@ -4,10 +4,6 @@ description: Technical specification for Tempo payment lanes ensuring dedicated # Payment Lane Specification -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) replaces the pre-T5 TIP-20 prefix-only consensus classifier with TIP-1045's allow-listed call shapes ([TIP-1045](https://tips.sh/1045)). The allow-list covers TIP-20 calls and the new `TIP20ChannelReserve` precompile ([TIP-1034](https://tips.sh/1034)), so payment-channel reserve transactions become first-class payment-lane traffic. Indexers, explorers, and payment processors that classify "payments" should pick up the new selector list before activation. Until T5 activates, the prefix-based classification described below still applies. -::: - ## Abstract This specification introduces a second consensus gas constraint for **non-payment** transactions. Transactions are classified as either payments or non-payments based solely on their transaction data, without requiring any access to blockchain state. For a block to be valid, total `gas_used` by the block must be less than the `gas_limit`. Non-payment transactions executed in the proposer's lane (i.e. before the gas incentive section) must consume at most `general_gas_limit`, a new field added to the header. Once that budget is exhausted, additional inclusion is constrained by the remaining shared gas budget. @@ -34,14 +30,14 @@ Non-payment transactions in the proposer's lane can only fill up to `general_gas A transaction is classified as a **payment transaction** when: - 1. the recipient address (`tx.to`) starts with the TIP-20 payment prefix `0x20c0000000000000000000000000`, or, - 2. for TempoTransactions, every entry in `tx.calls` targets an address starting with the TIP-20 payment prefix `0x20c0000000000000000000000000`. +1. Every call in the transaction matches an allow-listed payment call shape. +2. The transaction `access_list` is empty. +3. The transaction `authorization_list` and `tempo_authorization_list` are empty. +4. If `key_authorization` is present, `len(rlp(key_authorization)) <= 1024` bytes. This classification is performed entirely on the transaction payload, no account state is consulted. -:::info -Later upgrades may enable other kinds of transactions to be classified as payment transactions as well. -::: +The payment call allow-list includes TIP-20 payment and mint/burn/approval calls, plus the `TIP20ChannelReserve` payment-channel precompile calls. Calls with unrecognized selectors, malformed ABI encoding, disallowed targets, non-empty auxiliary payloads, or dynamic calldata above the allow-list size bound are classified as non-payment transactions. See [TIP-1045](https://tips.sh/1045) for the complete selector table and ABI constraints. ### 2. Ordering of Transactions diff --git a/src/pages/protocol/exchange/index.mdx b/src/pages/protocol/exchange/index.mdx index 2e406eb5..be698ad4 100644 --- a/src/pages/protocol/exchange/index.mdx +++ b/src/pages/protocol/exchange/index.mdx @@ -12,18 +12,12 @@ The exchange operates as a singleton precompiled contract at address `0xdec00000 Trading pairs are determined by each token's quote token. All TIP-20 tokens specify a quote token for trading on the exchange. See [Quote Tokens](/protocol/exchange/quote-tokens) for more information on quote token selection and the optional [pathUSD](/protocol/exchange/quote-tokens#pathusd) stablecoin. See the [Stablecoin DEX Specification](/protocol/exchange/spec) for detailed information on the exchange structure. -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) changes flip-order behavior: `flipTick == tick` becomes valid ([TIP-1030](https://tips.sh/1030)), and a filled flip order keeps the same `orderId` and emits a new `OrderFlipped` event instead of a fresh `OrderPlaced` ([TIP-1056](https://tips.sh/1056)). See the [T4 → T5 migration appendix](/protocol/exchange/providing-liquidity#t4--t5-migration) on the Providing Liquidity page. - -T5 also adds the StablecoinDEX to the [Implicit Approvals List](/protocol/upgrades/t5#tip-1035-implicit-approvals-list) ([TIP-1035](https://tips.sh/1035)), so users no longer need to pre-approve the DEX before placing orders or swapping — saving a wallet prompt and the gas cost of an allowance write. -::: - The exchange supports three types of orders, each with different execution behavior: | Order Type | Description | |------------|-------------| | [**Limit Orders**](/protocol/exchange/providing-liquidity#limit-orders) | Place orders at specific price levels that wait in the book until matched or cancelled. Orders are added to the book immediately when placed. | -| [**Flip Orders**](/protocol/exchange/providing-liquidity#flip-orders) | Special orders that automatically reverse to the opposite side when completely filled, acting like a perpetual liquidity pool. When a flip order is fully filled, a new order is immediately created on the opposite side. | +| [**Flip Orders**](/protocol/exchange/providing-liquidity#flip-orders) | Special orders that automatically reverse to the opposite side when completely filled, acting like a perpetual liquidity pool. When a flip order is fully filled, the same `orderId` is rewritten on the opposite side and emits `OrderFlipped`. | | [**Market Orders**](/protocol/exchange/executing-swaps#swap-functions) | Execute immediately against the best available orders in the book (via swap functions). Swaps and cancellations execute immediately within the transaction. | For the complete execution mechanics, see the [Stablecoin DEX Specification](/protocol/exchange/spec). diff --git a/src/pages/protocol/exchange/providing-liquidity.mdx b/src/pages/protocol/exchange/providing-liquidity.mdx index 90c0b098..cbea348a 100644 --- a/src/pages/protocol/exchange/providing-liquidity.mdx +++ b/src/pages/protocol/exchange/providing-liquidity.mdx @@ -64,14 +64,6 @@ uint128 orderId = exchange.place( ### Flip Orders -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) changes flip-order behavior in two ways: -- `flipTick == tick` becomes valid ([TIP-1030](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1030.md)) -- A filled flip order keeps the same `orderId` and emits a new `OrderFlipped` event instead of a fresh `OrderPlaced` ([TIP-1056](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1056.md)) - -Until T5 activates, the behavior described below still applies. Developers updating indexers, SDKs, or contract code should see the [T4 → T5 migration appendix](#t4--t5-migration) below. -::: - Special orders that automatically reverse to the opposite side when completely filled, creating perpetual liquidity similar to an automated market maker pool. ```solidity @@ -87,8 +79,8 @@ function placeFlip( **Parameters:** - All parameters from `place()`, plus: - `flipTick` - The price where the order will flip to when filled - - Must be greater than `tick` if `isBid` is true - - Must be less than `tick` if `isBid` is false + - Must be greater than or equal to `tick` if `isBid` is true + - Must be less than or equal to `tick` if `isBid` is false **Returns:** - `orderId` - Unique identifier for this flip order @@ -107,7 +99,7 @@ uint128 orderId = exchange.placeFlip( When this order is completely filled: 1. You buy 1000 USDG at $0.9990 -2. A new order automatically sells 1000 USDG at $1.0010 +2. The same order ID automatically rests as an ask for 1000 USDG at $1.0010 and emits `OrderFlipped` 3. When that fills, it flips back to a bid at $0.9990 4. This continues indefinitely, earning the spread each time @@ -160,7 +152,7 @@ Orders follow a specific lifecycle: 2. **Filling**: As market orders execute against your order: - Your order fills partially or completely - Proceeds are credited to your DEX balance - - If a flip order fills completely, a new order is immediately created on the opposite side + - If a flip order fills completely, the same `orderId` is immediately rewritten on the opposite side and an `OrderFlipped` event is emitted ## Cancelling Orders @@ -184,19 +176,13 @@ Cancellations execute immediately, and any unfilled portion of your order is ref You can only cancel your own orders. Attempting to cancel another user's order will revert. ::: -## T4 → T5 migration - -:::info[Migration appendix] -This section is for DEX integrators preparing for the [T5 network upgrade](/protocol/upgrades/t5). For a summary of what changes, see the [Coming with T5 callout](#flip-orders) under Flip Orders. Once T5 activates on Testnet (Moderato) and Mainnet (Presto), the body of this page will be rewritten to describe post-T5 behavior canonically and this appendix will be removed in a future docs revision. -::: - -### Action items for integrators +## Flip-order indexing **Indexers and analytics:** -- Subscribe to the new `OrderFlipped(orderId, newSide, newTick, ...)` event on the DEX -- Stop expecting a freshly allocated `orderId` after each flip; key order state by `(orderId)` and let it change side and tick over its lifetime -- Stop expecting `nextOrderId` to advance per flip +- Subscribe to the `OrderFlipped(orderId, newSide, newTick, ...)` event on the DEX +- Key order state by `orderId` and let it change side and tick over its lifetime +- Do not expect `nextOrderId` to advance per flip **Frontends and SDKs:** @@ -204,8 +190,6 @@ This section is for DEX integrators preparing for the [T5 network upgrade](/prot **Smart contracts and tooling:** -- Drop any assertion that `flipTick != tick` -- If you support both pre-T5 and post-T5 networks, branch on the network version or activation timestamp +- Do not assert that `flipTick != tick`; same-tick flips are valid See the [compatibility section of TIP-1056](https://tips.sh/1056#compatibility) for additional migration guidance. - diff --git a/src/pages/protocol/exchange/spec.mdx b/src/pages/protocol/exchange/spec.mdx index 1006f64d..22e78904 100644 --- a/src/pages/protocol/exchange/spec.mdx +++ b/src/pages/protocol/exchange/spec.mdx @@ -34,15 +34,7 @@ The contract maintains per‑user, per‑token internal balances. Order placemen #### Flip orders -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) changes flip-order behavior in two ways: -- `flipTick == tick` becomes valid ([TIP-1030](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1030.md)) -- A filled flip order keeps the same `orderId` and emits a new `OrderFlipped` event instead of a fresh `OrderPlaced` ([TIP-1056](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1056.md)) - -Until T5 activates, the behavior described below still applies. Indexers, SDKs, and contract code should see the [T4 → T5 migration appendix](/protocol/exchange/providing-liquidity#t4--t5-migration) on the Providing Liquidity page. -::: - -A flip order behaves like a normal resting order until it is fully filled. When filled, the exchange places a new order for the same maker on the opposite side at a configured `flipTick` (which must be greater than `tick` for bids and less for asks). This enables passive liquidity with flexible strategies. +A flip order behaves like a normal resting order until it is fully filled. When filled, the exchange rewrites the order in place under the same `orderId` on the opposite side at a configured `flipTick`. The `flipTick` must be greater than or equal to `tick` for bids and less than or equal to `tick` for asks. The flip emits `OrderFlipped` instead of `OrderPlaced`, and `nextOrderId` does not advance. This enables passive liquidity with flexible strategies. When a flip order flips, it draws escrow exclusively from the maker's internal exchange balance. Unlike initial order placement, the exchange does not fall back to `transferFrom` if the internal balance is insufficient—the flip simply does not occur. This ensures that flip execution is self-contained and does not require additional token approvals or external balance checks at fill time. @@ -181,13 +173,13 @@ Notes: function placeFlip(address token, uint128 amount, bool isBid, int16 tick, int16 flipTick) external returns (uint128 orderId); ``` -Like `place`, but marks the order as a flip order. When fully filled, a new order for the same maker is scheduled on the opposite side at `flipTick` (which must be greater than `tick` for bids and less for asks). +Like `place`, but marks the order as a flip order. When fully filled, the same `orderId` is rewritten in place on the opposite side at `flipTick` (which must be greater than or equal to `tick` for bids and less than or equal to `tick` for asks). Notes: - Both `tick` and `flipTick` must be within `[MIN_TICK, MAX_TICK]` and divisible by `TICK_SPACING` (10). - When the order flips, escrow is drawn exclusively from the maker's internal exchange balance. If the internal balance is insufficient, the flip silently fails—no `transferFrom` is attempted, even if the maker has sufficient external balance and approval. -- The maker must be authorized by the TIP-403 transfer policies of both the base and quote tokens, both at initial placement and when the order flips. If the maker becomes unauthorized before a flip, the flip silently fails and no new order is created (although the existing order is executed). +- The maker must be authorized by the TIP-403 transfer policies of both the base and quote tokens, both at initial placement and when the order flips. If the maker becomes unauthorized before a flip, the flip silently fails and no flipped order is inserted (although the existing order is executed). ```solidity function cancel(uint128 orderId) external; @@ -240,6 +232,7 @@ Executes an exact‑out swap. Deducts the actual input from the caller’s inter ```solidity event PairCreated(bytes32 indexed key, address indexed base, address indexed quote); event OrderPlaced(uint128 indexed orderId, address indexed maker, address indexed token, uint128 amount, bool isBid, int16 tick, bool isFlipOrder, int16 flipTick); +event OrderFlipped(uint128 indexed orderId, address indexed maker, address indexed token, uint128 amount, bool isBid, int16 tick, int16 flipTick); event OrderCancelled(uint128 indexed orderId); event OrderFilled(uint128 indexed orderId, address indexed maker, address indexed taker, uint128 amountFilled, bool partialFill); ``` @@ -256,4 +249,3 @@ error Unauthorized(); - Authorization: `UNAUTHORIZED` (cancel not by maker) - Stale orders: `ORDER_NOT_STALE` (cancelStaleOrder when maker is still authorized) - Balance: `INSUFFICIENT_BALANCE` (withdraw) - diff --git a/src/pages/protocol/fees/spec-fee-amm.mdx b/src/pages/protocol/fees/spec-fee-amm.mdx index 6d862e57..dc19c37d 100644 --- a/src/pages/protocol/fees/spec-fee-amm.mdx +++ b/src/pages/protocol/fees/spec-fee-amm.mdx @@ -4,10 +4,6 @@ description: Technical specification for the Fee AMM enabling automatic stableco # Fee AMM Specification -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) introduces two-hop FeeAMM routing ([TIP-1033](https://tips.sh/1033)). If there is insufficient liquidity on the direct pool between the user's fee token and the validator token, the FeeAMM then considers routing from the user's fee token to that token's quote token to the validator's token. As a result, post-T5 fee conversion may now reserve and consume liquidity from two pools. -::: - ## Abstract This specification defines a system of one-way Automated Market Makers (AMMs) designed to facilitate gas fee payments from a user using one stablecoin (the `userToken`) to a validator who prefers a different stablecoin (the `validatorToken`). Each AMM handles fee swaps from a `userToken` to a `validatorToken` at one price (0.9970 `validatorToken` per `userToken`), and allows rebalancing in the other direction at another fixed price (1.0015 `userToken` per `validatorToken`). @@ -203,6 +199,7 @@ Returns the amount of accumulated fees for a validator and specific token that c - **Purpose**: Convert tokens paid by users as fees to tokens preferred by validators - **Settlement**: Immediate during transaction execution - **Access**: Protocol only +- **Routing**: If the direct `userToken → validatorToken` pool has insufficient liquidity, the Fee AMM tries one two-hop route through `userToken.quoteToken()`. Both hops must have sufficient liquidity. The validator receives `floor(floor(actualSpending × 9970 / 10000) × 9970 / 10000)` on the two-hop path. #### Rebalancing Swaps - **Rate**: Fixed at n=0.9985 (swapper receives 1 of the user token for every 0.9985 that they put in of the validator's preferred token) diff --git a/src/pages/protocol/tip20/overview.mdx b/src/pages/protocol/tip20/overview.mdx index bd1c36aa..b3cd7ea6 100644 --- a/src/pages/protocol/tip20/overview.mdx +++ b/src/pages/protocol/tip20/overview.mdx @@ -6,14 +6,7 @@ import { Cards, Card } from 'vocs' # TIP-20 Token Standard -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) adds three TIP-20 features: -- An optional on-chain `logoURI` field on every token so wallets and explorers can render the official icon without an off-chain registry ([TIP-1026](https://tips.sh/1026)) -- An Implicit Approvals List that lets the StablecoinDEX, FeeAMM, and the new payment-channel reserve precompile pull TIP-20 tokens without a prior `approve` transaction ([TIP-1035](https://tips.sh/1035)) -- An enshrined `TIP20ChannelReserve` precompile at `0x4D505000…0000` for MPP and other session-based payment flows ([TIP-1034](https://tips.sh/1034)) - -Existing tokens continue to work unchanged. See the [T4 → T5 migration appendix on the TIP-20 spec](/protocol/tip20/spec#t4--t5-migration) for the full ABI surface. -::: +TIP-20 is Tempo's native token standard for stablecoins and payment tokens. TIP-20 is designed for stablecoin payments, and is the foundation for many token-related functions on Tempo including transaction fees, payment lanes, DEX quote tokens, optimized routing for DEX liquidity, optional on-chain token `logoURI` metadata, implicit approvals for listed precompiles, and enshrined payment-channel reserve flows. :::info[Coming with T6] The [T6 network upgrade](/protocol/upgrades/t6) adds account-level receive policies for TIP-20 transfers and mints ([TIP-1028](https://tips.sh/1028)). A receiver can choose which tokens and senders they accept, helping wallets and deposit addresses avoid unsupported assets, unwanted counterparties, and wrong-token deposits. If a receive policy blocks delivery, the transfer or mint still succeeds, but funds are redirected to `ReceivePolicyGuard` so they can be claimed later. @@ -21,8 +14,6 @@ The [T6 network upgrade](/protocol/upgrades/t6) adds account-level receive polic See the [T5 → T6 migration appendix on the TIP-20 spec](/protocol/tip20/spec#t5--t6-migration) for the TIP-20 surface area. ::: -TIP-20 is Tempo's native token standard for stablecoins and payment tokens. TIP-20 is designed for stablecoin payments, and is the foundation for many token-related functions on Tempo including transaction fees, payment lanes, DEX quote tokens, and optimized routing for DEX liquidity on Tempo. - All TIP-20 tokens are created by interacting with the [TIP-20 Factory contract](/protocol/tip20/spec#tip20factory), calling the `createToken` function. If you're issuing a stablecoin on Tempo, we **strongly recommend** using the TIP-20 standard. Learn more about the benefits, or follow the guide on issuance [here](/guide/issuance). ## Benefits & Features of TIP-20 Tokens diff --git a/src/pages/protocol/tip20/spec.mdx b/src/pages/protocol/tip20/spec.mdx index a0e938b5..bef87e9b 100644 --- a/src/pages/protocol/tip20/spec.mdx +++ b/src/pages/protocol/tip20/spec.mdx @@ -143,6 +143,9 @@ interface ITIP20 { /// @return The transfer policy ID function transferPolicyId() external view returns (uint64); + /// @notice Returns the on-chain logo URI for this token (empty if unset) + function logoURI() external view returns (string memory); + // ========================================================================= // Admin Functions // ========================================================================= @@ -172,6 +175,14 @@ interface ITIP20 { /// @param newSupplyCap The new supply cap (cannot be less than current supply) function setSupplyCap(uint256 newSupplyCap) external; + /// @notice Updates the logo URI (requires DEFAULT_ADMIN_ROLE) + /// @param newLogoURI The new logo URI (max 256 bytes; empty string clears the field) + /// @dev If non-empty, MUST be a syntactically valid URI with a scheme in the + /// allowlist {https, http, ipfs, data} (case-insensitive). + /// Reverts LogoURITooLong if length > 256 bytes. + /// Reverts InvalidLogoURI if the scheme is not in the allowlist or the URI is malformed. + function setLogoURI(string calldata newLogoURI) external; + // ========================================================================= // Role Management // ========================================================================= @@ -368,6 +379,11 @@ interface ITIP20 { address indexed sender ); + /// @notice Emitted when the logo URI changes + /// @param updater The address that updated the logo URI (msg.sender) + /// @param newLogoURI The new logo URI value + event LogoURIUpdated(address indexed updater, string newLogoURI); + // ========================================================================= // Errors // ========================================================================= @@ -421,6 +437,12 @@ interface ITIP20 { /// @notice The caller does not have the required role or permission for this operation error Unauthorized(); + /// @notice The provided logoURI exceeds the 256-byte cap + error LogoURITooLong(); + + /// @notice The provided logoURI is malformed or uses a scheme outside the allowlist + error InvalidLogoURI(); + } ``` @@ -471,6 +493,13 @@ TIP-20 tokens support [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) `permi The `DOMAIN_SEPARATOR` is computed dynamically on every call using `block.chainid`, so it remains correct after a chain fork. Each owner has a monotonically increasing `nonce` to prevent replay. Only `v = 27` or `v = 28` is accepted; `v = 0` or `v = 1` is intentionally **not** normalized (see [TIP-1004](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1004.md) for rationale). +## Logo URI (TIP-1026) +Every TIP-20 exposes an optional on-chain `logoURI`, added in the [T5 network upgrade](/protocol/upgrades/t5) ([TIP-1026](https://tips.sh/1026)). Wallets and explorers read the icon directly from the token contract via `logoURI()`, without an off-chain registry round-trip. Tokens without a `logoURI` continue to work; the field is empty by default. + +The admin (`DEFAULT_ADMIN_ROLE`) sets or clears it via `setLogoURI(string newLogoURI)`, which emits `LogoURIUpdated(msg.sender, newLogoURI)`. An empty string is valid and clears the field. A non-empty value must be at most 256 bytes (`LogoURITooLong` otherwise) and a syntactically valid URI whose scheme is in the allowlist `{https, http, ipfs, data}`, matched case-insensitively (`InvalidLogoURI` otherwise). + +Per [TIP-1026's recommended formats](https://tips.sh/1026#recommended-formats), use a square, single-frame rasterized image (PNG or WebP). SVG is allowed by the scheme allowlist but not recommended — integrators that accept SVG must follow TIP-1026's SVG-handling guidance. + ## Pause Controls Pause controls `pause` and `unpause` govern all transfer operations and reward related flows. When paused, transfers and memo transfers halt, but administrative and configuration functions remain allowed. The `paused()` getter reflects the current state and must be checked by all affected entrypoints. @@ -488,6 +517,19 @@ System level functions `systemTransferFrom`, `transferFeePreTx`, and `transferFe `transferFeePreTx` respects the token's pause state and will revert if the token is paused. However, `transferFeePostTx` is intentionally allowed to execute even when the token is paused. This ensures that a transaction which pauses the token can still complete successfully and receive its fee refund. Apart from this specific refund transfer, no other token transfers can occur after a pause event. +### Implicit approvals for listed precompiles (TIP-1035) +An Implicit Approval List names the precompiles that may pull TIP-20 tokens without a prior `approve`. Listed precompiles call the internal `system_transfer_from(from, to, amount)` entrypoint, which: + +- Is **not** part of the public TIP-20 ABI and is **not** callable by external contracts or EOAs. +- Skips allowance checks and the allowance storage write. +- Still enforces balance checks, TIP-403 transfer policies, and AccountKeychain spending limits. +- Emits the standard TIP-20 `Transfer` event. + +This generalizes the system-only path described above (`systemTransferFrom`, `transferFeePreTx`, `transferFeePostTx`) to an allow-list of precompiles — the StablecoinDEX, FeeAMM, and the `TIP20ChannelReserve` precompile. Normal `approve`, `permit`, `allowance`, and `transferFrom` behavior is unchanged. + +### Payment-channel reserve (TIP-1034) +The enshrined `TIP20ChannelReserve` precompile at [`0x4D50500000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x4D50500000000000000000000000000000000000) (ASCII `MPP`) is a TIP-20 consumer rather than a change to the TIP-20 contract itself — it pulls funds via the implicit-approval path above and emits standard `Transfer` events from the host TIP-20. See the [enshrined TIP-20 reserve channel section of the T5 page](/protocol/upgrades/t5#enshrined-tip-20-reserve-channel) for the channel lifecycle, channel ID derivation, and event surface. + ## Token Rewards Distribution See [rewards distribution](/protocol/tip20-rewards/spec) for more information. @@ -508,6 +550,8 @@ When creating a token, the factory performs several checks to guarantee consiste `transferPolicyId = 1`, `supplyCap = type(uint128).max`, `paused = false`, and `totalSupply = 0`. - The provided `admin` address receives `DEFAULT_ADMIN_ROLE`, enabling it to manage roles and token configurations. +The factory provides two `createToken` overloads: the original 6-argument form, and a 7-argument form that additionally sets an initial [`logoURI`](#logo-uri-tip-1026) at creation (validated with the same rules as `setLogoURI`). The 6-argument overload is unchanged. + The complete `TIP20Factory` interface is defined below: ```solidity @@ -545,6 +589,22 @@ interface ITIP20Factory { bytes32 salt ) external returns (address token); + /// @notice Creates and deploys a new TIP-20 token with an initial logoURI + /// @dev Identical to the 6-arg overload, but additionally sets logoURI at creation. + /// Validation rules for logoURI are the same as setLogoURI (256-byte cap, + /// allowlisted schemes, syntactically valid URI). Empty string is valid and + /// leaves logoURI unset (no LogoURIUpdated event emitted). When non-empty, the + /// new token emits LogoURIUpdated(msg.sender, logoURI) from its own address. + function createToken( + string memory name, + string memory symbol, + string memory currency, + ITIP20 quoteToken, + address admin, + bytes32 salt, + string memory logoURI + ) external returns (address token); + // ========================================================================= // Helpers // ========================================================================= @@ -603,82 +663,7 @@ interface ITIP20Factory { - When `paused` is `true`, no functions that move tokens (`transfer`, `transferFrom`, memo variants, `systemTransferFrom`, `transferFeePreTx`, `distributeReward`, `setRewardRecipient`, `claimRewards`) can succeed. - TIP20 tokens cannot be transferred to another TIP20 token contract address. - `systemTransferFrom`, `transferFeePreTx`, and `transferFeePostTx` never change `totalSupply()`. - -## T4 → T5 migration - -:::info[Migration appendix] -This section captures TIP-20 changes shipping with the [T5 network upgrade](/protocol/upgrades/t5). Until T5 activates on testnet and mainnet, the spec above remains canonical. After T5 activation, the items below will be folded into the body and this appendix will be removed. -::: - -T5 introduces three additions that affect the TIP-20 surface: - -### TIP-1026: optional on-chain `logoURI` - -Adds an optional `logoURI` string (256-byte cap) to every TIP-20, admin-mutable via `setLogoURI`. Tokens without a `logoURI` continue to work; the field is empty by default. - -New surface area on `ITIP20`: - -```solidity -/// @notice Returns the on-chain logo URI for this token (empty if unset) -function logoURI() external view returns (string memory); - -/// @notice Updates the logo URI (requires DEFAULT_ADMIN_ROLE) -/// @param newLogoURI The new logo URI (max 256 bytes; empty string clears the field) -/// @dev If non-empty, MUST be a syntactically valid URI with a scheme in the -/// allowlist {https, http, ipfs, data} (case-insensitive). -/// Reverts LogoURITooLong if length > 256 bytes. -/// Reverts InvalidLogoURI if the scheme is not in the allowlist or the URI is malformed. -function setLogoURI(string calldata newLogoURI) external; - -/// @notice Emitted when the logo URI changes -/// @param updater The address that updated the logo URI (msg.sender) -/// @param newLogoURI The new logo URI value -event LogoURIUpdated(address indexed updater, string newLogoURI); - -/// @notice The provided logoURI exceeds the 256-byte cap -error LogoURITooLong(); - -/// @notice The provided logoURI is malformed or uses a scheme outside the allowlist -error InvalidLogoURI(); -``` - -The `TIP20Factory` gains a 7-arg `createToken` overload that accepts an initial `logoURI`. When non-empty, the new token emits `LogoURIUpdated(msg.sender, logoURI)` from its own address at creation time. The existing 6-arg overload is unchanged. - -```solidity -/// @notice Creates and deploys a new TIP-20 token with an initial logoURI -/// @dev Identical to the 6-arg overload, but additionally sets logoURI at creation. -/// Validation rules for logoURI are the same as setLogoURI (256-byte cap, -/// allowlisted schemes, syntactically valid URI). Empty string is valid and -/// leaves logoURI unset (no LogoURIUpdated event emitted). -function createToken( - string memory name, - string memory symbol, - string memory currency, - address quoteToken, - address admin, - bytes32 salt, - string memory logoURI -) external returns (address token); -``` - -Per [TIP-1026's recommended formats](https://tips.sh/1026#recommended-formats), use a square, single-frame rasterized image (PNG or WebP) for `logoURI`. SVG is allowed by the scheme allowlist but not recommended — integrators that accept SVG must follow TIP-1026's SVG-handling guidance. - -### TIP-1035: implicit approvals for listed precompiles - -T5 introduces an Implicit Approval List of precompiles that may pull TIP-20 tokens without a prior `approve`. Listed precompiles call the internal `system_transfer_from(from, to, amount)` entrypoint, which: - -- Is **not** part of the public TIP-20 ABI and is **not** callable by external contracts or EOAs. -- Skips allowance checks and the allowance storage write. -- Still enforces balance checks, TIP-403 transfer policies, and AccountKeychain spending limits. -- Emits the standard TIP-20 `Transfer` event. - -This generalizes the existing system-only path (previously documented as `systemTransferFrom`, `transferFeePreTx`, `transferFeePostTx`) to a hardfork-gated allow-list of precompiles — initially the StablecoinDEX, FeeAMM, and the new `TIP20ChannelReserve` precompile. Normal `approve`, `permit`, `allowance`, and `transferFrom` behavior is unchanged. - -### TIP-1034: `TIP20ChannelReserve` precompile cross-reference - -T5 ships an enshrined TIP-20 payment-channel reserve precompile at [`0x4D50500000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x4D50500000000000000000000000000000000000) (ASCII `MPP`). Channel reserve is a TIP-20 consumer rather than a change to the TIP-20 contract itself — it pulls funds via the implicit-approval path described above and emits standard `Transfer` events from the host TIP-20. - -See the [Enshrined TIP-20 reserve channel section of the T5 page](/protocol/upgrades/t5#enshrined-tip-20-reserve-channel-tip-1034) for the channel lifecycle, channel ID derivation, and event surface. +- `bytes(logoURI()).length` must always be `<= 256`. ## T5 → T6 migration diff --git a/src/pages/protocol/transactions/AccountKeychain.mdx b/src/pages/protocol/transactions/AccountKeychain.mdx index cbe28b6c..699fe322 100644 --- a/src/pages/protocol/transactions/AccountKeychain.mdx +++ b/src/pages/protocol/transactions/AccountKeychain.mdx @@ -171,9 +171,7 @@ interface IAccountKeychain { ### Key Authorization -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) adds an optional `witness: bytes32` field to `key_authorization` ([TIP-1053](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1053.md)). The protocol includes the witness in the signing hash and emits it when the key authorization is registered, but otherwise treats it as opaque and application-defined. This lets one signature both authorize an access key and bind to an application challenge — collapsing the two-prompt flow that "Sign-In with Tempo" style apps use today into a single signature. No breaking change; tooling should start populating and reading the new field after activation. -::: +- `key_authorization` includes an optional trailing `witness: bytes32` field. When present, the witness is included in the signing hash, checked against the account's burned-witness set, and emitted when the key authorization is registered. The protocol otherwise treats it as opaque and application-defined, so apps can bind a single access-key authorization signature to an offchain challenge. :::info[Coming with T6 — SDK encoders/decoders] The [T6 network upgrade](/protocol/upgrades/t6) adds **admin access keys** ([TIP-1049](https://tips.sh/1049)). For partners maintaining transaction tooling, the wire-level change is two new trailing optional fields on the `KeyAuthorization` RLP payload: @@ -317,4 +315,3 @@ Access Keys cannot escalate their own privileges because: 1. User signs Passkey prompt → signs transaction calling `revokeKey(keyId)`, `updateSpendingLimit(...)`, `setAllowedCalls(...)`, or `removeAllowedCalls(...)` 2. Transaction executes, marking the Access Key as inactive or updating its restrictions 3. Future transactions signed by that Access Key are rejected (after revocation) or evaluated against the updated restrictions - diff --git a/src/pages/protocol/upgrades/t5.mdx b/src/pages/protocol/upgrades/t5.mdx index 130ceea0..bf219f8a 100644 --- a/src/pages/protocol/upgrades/t5.mdx +++ b/src/pages/protocol/upgrades/t5.mdx @@ -5,10 +5,10 @@ description: Details and timeline for the T5 network upgrade, including the ensh # T5 Network Upgrade -T5 is Tempo's latest network upgrade. It introduces an enshrined TIP-20 reserve channel precompile for MPP and similar session-based payment flows (cutting channel-open gas by up to 72% versus the legacy MPP contract), payment lane classification in consensus, DEX improvements (same-tick flip orders and persistent order IDs across flips), multihop FeeAMM routing, an on-chain `logoURI` field for TIP-20 tokens, an Implicit Approvals List for gas-efficient internal transfers, and a witness digest binding for one-signature key authorization flows. +T5 is Tempo's latest network upgrade. It lowered costs for session-based payments, improved DEX flip-order tracking, simplified fee-token routing, added on-chain token logos, and added witness binding for key authorization flows. :::info[T5 status] -T5 is live on testnet and is not yet active on mainnet. The features described on this page are active on testnet and become live on mainnet at the activation timestamp below. +T5 is live on testnet and mainnet. ::: ## Timeline @@ -18,120 +18,135 @@ T5 is live on testnet and is not yet active on mainnet. The features described o | Testnet | June 3, 2026 4pm CEST | 1780495200 | | Mainnet | June 9, 2026 4pm CEST | 1781013600 | -Mainnet node operators must upgrade to the T5-compatible release (v1.8.0) before the mainnet activation timestamp. +Mainnet node operators needed to upgrade to the T5-compatible release (v1.8.0) before the mainnet activation timestamp. ## Overview -T5 introduces the following changes: -- An enshrined TIP-20 reserve channel precompile for MPP and other session-based payment flows ([TIP-1034](https://tips.sh/1034)) -- Consensus-level classification of payment-lane-eligible transactions ([TIP-1045](https://tips.sh/1045)) -- Same-tick flip orders on the DEX ([TIP-1030](https://tips.sh/1030)) -- Persistent order IDs across flips ([TIP-1056](https://tips.sh/1056)) -- Multihop FeeAMM routing for validator payout tokens ([TIP-1033](https://tips.sh/1033)) -- An optional on-chain `logoURI` field for TIP-20 tokens ([TIP-1026](https://tips.sh/1026)) -- An Implicit Approvals List enabling listed precompiles to pull TIP-20 tokens without a prior approval ([TIP-1035](https://tips.sh/1035)) -- A witness digest field in key authorizations to bind one signature to an application challenge ([TIP-1053](https://tips.sh/1053)) +T5 focuses on four integration areas, plus a storage correctness fix: -## Integration changes +- **Cheaper payment sessions.** The `TIP20ChannelReserve` precompile gives MPP and other session-based payment apps a protocol-native reserve path. +- **Clearer DEX state.** Flip orders can use the same tick on both sides and keep the same `orderId` after each flip. +- **Simpler fee-token liquidity.** FeeAMM routing can use two hops, so issuers usually do not need a direct pool against every validator payout token. +- **Better token and key metadata.** TIP-20 tokens can expose an on-chain `logoURI`, listed precompiles can pull TIP-20 tokens without a separate approval, and key authorizations can include an app-defined witness digest. +- **Storage correctness fix.** Shrinking writes to dynamic precompile storage clear their stale tail slots at the hardfork boundary ([TIP-1057](https://tips.sh/1057)). -Most of T5 is additive. The notes below cover behaviors that integrators, indexers, and tooling should pick up before mainnet activation. +Most T5 changes are additive: existing TIP-20 tokens, MPP contracts, and non-flip DEX flows continue to work. -### Enshrined TIP-20 reserve channel (TIP-1034) +## Features -Not a breaking change at the contract level — the existing application-level MPP reserve contract continues to work after T5. The new precompile lives at [`0x4D50500000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x4D50500000000000000000000000000000000000) (ASCII `MPP`). To migrate to the precompile path, MPP libraries need to be upgraded to versions that target it; new releases will be linked under [Compatible SDK releases](#compatible-sdk-releases) once published. Tooling that monitors or interacts with MPP reserve should be aware of both surfaces during the transition. +### Enshrined TIP-20 reserve channel -Migrating to the precompile cuts measured gas by ~72% for opening a channel against an existing reserve balance, ~39% for a first-time reserve open, and 13–26% across close and top-up operations. See the full [gas comparison](#gas-comparison) below. +The reserve precompile lives at [`0x4D50500000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x4D50500000000000000000000000000000000000) (ASCII `MPP`). It replaces the application-level MPP reserve contract for new integrations, while the existing contract continues to work. -SDKs that target the precompile also benefit from extra gas savings thanks to [implicit approvals](#tip-1035-implicit-approvals-list): the channel reserve can pull TIP-20 tokens with the internal `system_transfer_from` path instead of a public `transferFrom`, avoiding the separate approval transaction and allowance storage write. +Measured gas savings versus the legacy reserve contract: -### Payment lane selector allow-list (TIP-1045) +| Operation | Legacy contract | Enshrined reserve precompile | Gas reduction | +|---|---:|---:|---:| +| Open channel, existing reserve balance | 1,055,229 | 294,425 | 72% | +| Open channel, first reserve balance | 1,302,429 | 791,625 | 39% | +| Close existing channel | 85,118 | 62,913 | 26% | +| Top up existing channel | 53,724 | 46,805 | 13% | +| Top up and cancel close request | 58,785 | 48,680 | 17% | -Anything that classifies transactions as "payments" (indexers, explorers, payment processors) should pick up the new selector allow-list. The list covers TIP-20 calls and the new `TIP20ChannelReserve` precompile (TIP-1034). +These numbers cover only the channel operation itself. Under the legacy path, first-time users also had to send a separate `approve` transaction before opening a channel. With the precompile on the Implicit Approvals List, that approval round trip and allowance storage write are removed. -### Same-tick flip orders (TIP-1030) +Read the technical specification at [TIP-1034](https://tips.sh/1034). -`placeFlip` now allows `flipTick == tick`. There is no breaking change, but downstream code that assumes `flipTick` is strictly on the opposite side of `tick` will stop holding. +### Payment lane classification -### Persistent order IDs across flips (TIP-1056) +T5 moved payment-lane eligibility from local builder policy into consensus. The allow-list covers TIP-20 calls and the new `TIP20ChannelReserve` precompile, so reserve-channel transactions are classified consistently across the network. -Flipped orders keep the same `orderId` and emit a new `OrderFlipped` event instead of `OrderPlaced`. Indexers should handle `OrderFlipped` and stop expecting a new `orderId` per flip. Frontends and SDKs surfacing order status should display the persistent ID. See the [T4 → T5 migration appendix on the Providing Liquidity page](/protocol/exchange/providing-liquidity#t4--t5-migration) and the [compatibility section of TIP-1056](https://tips.sh/1056#compatibility). +Read the technical specification at [TIP-1045](https://tips.sh/1045). -### Optional `logoURI` in TIP-20 (TIP-1026) +### DEX flip-order improvements -Tokens without `logoURI` continue to work. New surface area: +The upgrade changed flip orders in two ways: -- A `logoURI()` view on every TIP-20 — wallets and explorers can read it directly instead of going through `tokenlist.tempo.xyz`. -- A new `LogoURIUpdated(address indexed updater, string newLogoURI)` event. When the new `createToken` overload is called with a non-empty `logoURI`, this event is emitted from the new token's address (not the factory) with `updater = msg.sender`. -- A new 7-arg `createToken` overload on the factory that accepts a `logoURI`. The previous overload is unchanged. -- `setLogoURI(string)` for admin-only updates (requires `DEFAULT_ADMIN_ROLE`). +- `flipTick == tick` is valid. +- A filled flip order keeps the same `orderId` and emits `OrderFlipped` instead of creating a new order with `OrderPlaced`. -`logoURI` is validated on-chain: max 256 bytes (reverts `LogoURITooLong`), and if non-empty must be a syntactically valid URI with a scheme in the allowlist `https`, `http`, `ipfs`, `data` (case-insensitive). Otherwise reverts `InvalidLogoURI`. Empty string is valid and clears the field. +This makes a market-making strategy easier to track over time. Indexers should treat `OrderFlipped` as the latest active state for that `orderId`. -Per [TIP-1026's recommended formats](https://tips.sh/1026#recommended-formats), use a square, single-frame rasterized image (PNG or WebP) for `logoURI`. SVG is allowed by the scheme allowlist but not recommended — integrators that accept SVG must follow TIP-1026's SVG-handling guidance. +Read the technical specifications at [TIP-1030](https://tips.sh/1030) and [TIP-1056](https://tips.sh/1056). -### Witness digest in key authorizations (TIP-1053) +### Multihop FeeAMM routing -`key_authorization` gains an optional `witness: bytes32` field. The protocol includes the witness in the signing hash and emits it when the key authorization is registered, but otherwise treats it as opaque and application-defined. No breaking change; tooling should start populating and reading the new field. +FeeAMM can now route through two pools when there is no usable direct pool between the user's fee token and the validator's payout token. -## Compatible SDK releases +For token issuers, this usually means pairing against one liquid quote token, such as `pathUSD`, instead of provisioning direct pools against every validator payout token. -T5-compatible SDK releases will be listed here as they ship. +Read the technical specification at [TIP-1033](https://tips.sh/1033). -These releases should prefer the TIP-1034 reserve precompile over the legacy MPP reserve contract. Besides using the protocol-native reserve surface, that path offers several gas-saving benefits, including packed reserve storage slots and [implicit approvals](#tip-1035-implicit-approvals-list). With implicit approvals, the precompile calls internal `system_transfer_from` rather than regular `transferFrom`, so users do not need a separate allowance approval and reserve flows avoid the gas cost of the approval write. +### Optional on-chain logoURI -## Feature TIPs +TIP-20 tokens can expose an optional `logoURI` field. Wallets and explorers can read the official token icon directly from the token contract instead of relying only on the tokenlist registry. -### TIP-1034: Enshrined TIP-20 Reserve Channel +The field is capped at 256 bytes, and non-empty values must use an allowed URI scheme: `https`, `http`, `ipfs`, or `data`. -[TIP-1034](https://tips.sh/1034) moves TIP-20 payment-channel reserve from an application-level Solidity contract into the protocol as a precompile, giving Tempo a native, canonical payment-channel primitive for MPP and other high-frequency payment apps. +Read the technical specification at [TIP-1026](https://tips.sh/1026). -As a precompile, reserve uses protocol-native capabilities directly: +### Implicit approvals -- **Simpler open/top-up flow:** channels can be opened or topped up in one transaction. -- **Cleaner channel identity:** channel IDs are derived from the transaction's replay-protected context hash, instead of requiring transaction-context access to be exposed to Solidity. -- **Reduced storage and lower cost:** immutable channel details live in calldata and `ChannelOpened` logs; the precompile stores only mutable channel state on-chain. -- **Stable integration surface:** one canonical protocol-level reserve interface, while internals can improve in future upgrades without changing the public API. +Listed protocol precompiles can pull TIP-20 tokens without a prior `approve`. This removes an extra wallet prompt and avoids the allowance storage write for native flows such as DEX orders, DEX swaps, FeeAMM fee collection, and reserve-channel operations. -#### Gas comparison +The internal transfer path is not part of the public TIP-20 ABI and cannot be called by EOAs or external contracts. It still enforces balance checks, TIP-403 transfer policies, AccountKeychain spending limits, and emits the standard TIP-20 `Transfer` event. -Measured gas usage for the enshrined reserve precompile versus the legacy MPP reserve contract: +Read the technical specification at [TIP-1035](https://tips.sh/1035). -| Operation | Legacy contract | Enshrined reserve precompile | Gas reduction | -|---|---:|---:|---:| -| Open channel, existing reserve balance | 1,055,229 | 294,425 | 72% | -| Open channel, first reserve balance | 1,302,429 | 791,625 | 39% | -| Close existing channel | 85,118 | 62,913 | 26% | -| Top up existing channel | 53,724 | 46,805 | 13% | -| Top up and cancel close request | 58,785 | 48,680 | 17% | +### Witness digest in key authorizations + +`key_authorization` now supports an optional `witness: bytes32` field. Apps can bind one key-authorization signature to an application challenge, which removes the need for a separate challenge signature in login or delegated-access flows. + +Read the technical specification at [TIP-1053](https://tips.sh/1053). -These numbers cover only the channel operation itself. Under the legacy path, first-time users also had to send a separate `approve` transaction before opening a channel; with the precompile on the [Implicit Approvals List (TIP-1035)](#tip-1035-implicit-approvals-list), that round-trip and the allowance storage write are eliminated, so end-to-end savings for new users are larger than the per-call numbers above. Snapshots are reproducible from [`crates/node/tests/it/gas/legacy_stream_channel_contract.rs`](https://github.com/tempoxyz/tempo/blob/main/crates/node/tests/it/gas/legacy_stream_channel_contract.rs) and [`crates/node/tests/it/gas/tip20_channel_reserve.rs`](https://github.com/tempoxyz/tempo/blob/main/crates/node/tests/it/gas/tip20_channel_reserve.rs) in `tempoxyz/tempo`. +### Storage correctness fix -### TIP-1045: Payment Lane Classification +T5 gates one precompile storage fix at the hardfork boundary. Overwriting a `Vec`, `String`, or `Bytes` value with a shorter one used to leave the trailing slots populated, so reads past the new length returned stale data. T5 clears those slots on shrinking writes. -[TIP-1045](https://tips.sh/1045) adds consensus rules that classify which transactions are eligible for the payment lane via a calldata selector allow-list enforced at the T5 hardfork. The allow-list covers TIP-20 calls and the new `TIP20ChannelReserve` precompile (TIP-1034), so reserve-channel transactions are first-class payment-lane traffic. This was previously a builder-level, locally-subjective policy; T5 enshrines it in consensus. +This changes storage state and gas at the activation boundary, but no public ABI changes and no integrator action is required. + +Read the technical specification at [TIP-1057](https://tips.sh/1057). + +## Compatible SDK releases + +T5-compatible SDK releases will be listed here as they ship. -### TIP-1030: Allow Same-Tick Flip Orders +These releases should prefer the `TIP20ChannelReserve` precompile over the legacy MPP reserve contract for new integrations. -[TIP-1030](https://tips.sh/1030) relaxes `placeFlip` so `flipTick == tick` is allowed, enabling a filled order to re-list on the opposite side at the exact same tick. Before T5, a bid flip order had to flip to a higher tick and an ask flip order had to flip to a lower tick — too restrictive for pegged or near-1:1 assets where a market maker may want to buy and sell at the same tick to support instant convertibility between tokens or wrappers. +## What operators and integrators should know -### TIP-1056: Keep Order IDs Across Flips +T5 is mostly additive. Integrators, indexers, wallets, explorers, and partner infrastructure should review the notes below. -[TIP-1056](https://tips.sh/1056) keeps the same `orderId` across flips, rewrites the order in place, and emits a new `OrderFlipped` event instead of `OrderPlaced`. Before T5, the DEX treated the flipped side as a new order — emitting `OrderFilled`, allocating a new `orderId`, emitting `OrderPlaced`, and advancing `nextOrderId` — which made one logical flip strategy look like a chain of unrelated orders. After T5, market makers and order-tracking UIs can follow a single flip order across its full lifecycle without stitching IDs together. +### For MPP and payment-session integrators -### TIP-1033: Multihop FeeAMM Routing +- Keep supporting the legacy reserve contract during the transition. +- Prefer the `TIP20ChannelReserve` precompile for new SDK releases. +- Update monitoring to recognize both reserve surfaces. +- Show channel-open, top-up, and close flows from the precompile path. -[TIP-1033](https://tips.sh/1033) lets validators support more payout tokens without requiring direct liquidity for every fee-token / payout-token pair. Before T5, validator onboarding had a direct-liquidity requirement for every supported token; as more stablecoins and TIP-20s come to Tempo, we want users to pay fees in many tokens while validators choose the token they receive. FeeAMM LPs and rebalancers should be aware that one fee conversion can now reserve and consume liquidity from two pools instead of one. +### For DEX indexers and frontends -For new token issuers this means fee-pool liquidity setup is simpler: instead of provisioning a pool against every validator payout token, an issuer can pair their token against a single liquid quote (e.g., `pathUSD`) and let multihop routing connect it to any validator payout token that has its own pathUSD pool. Pool reserves and route availability are visible in the [FeeAMM explorer view](https://explore.tempo.xyz/fee-amm). +- Index `OrderFlipped`. +- Treat `OrderFlipped` as the active state for the same `orderId`. +- Do not assume a filled flip order receives a new `orderId`. +- Remove checks that reject `flipTick == tick`. +- See the [flip-order indexing notes](/protocol/exchange/providing-liquidity#flip-order-indexing). -### TIP-1035: Implicit Approvals List +### For FeeAMM integrators -[TIP-1035](https://tips.sh/1035) defines a hardfork-gated Implicit Approval List of precompiles that may pull TIP-20 tokens without a prior approval, removing the extra wallet prompt and allowance write that native flows like StablecoinDEX order placement, DEX swaps, and FeeAMM fee collection used to require. Listed precompiles may call the internal `system_transfer_from(from, to, amount)` function. This function is not part of the public TIP-20 ABI and cannot be called by external contracts. It skips allowance checks and updates, but still enforces balance checks, TIP-403 transfer policies, AccountKeychain spending limits, and emits the standard TIP-20 `Transfer` event. Normal TIP-20 `approve`, `permit`, `allowance`, and `transferFrom` behavior is unchanged. +- Account for two-pool routes when quoting or explaining fee conversion. +- Show route availability from direct pools and multihop paths. +- Make clear that one conversion may reserve and consume liquidity from two pools. -### TIP-1026: Optional logoURI Field in TIP-20 +### For token issuers, wallets, and explorers -[TIP-1026](https://tips.sh/1026) adds an optional `logoURI` string field (256-byte cap) to TIP-20 tokens, admin-mutable via `setLogoURI`. Wallets and explorers can read token icons on-chain instead of relying on an off-chain token list. Token issuers can publish their official logo with the token, and any wallet or explorer can render it without a centralized list registration. +- Read `logoURI()` directly from TIP-20 contracts when available. +- Continue using the tokenlist for richer metadata and fallback icons. +- Watch `LogoURIUpdated(address indexed updater, string newLogoURI)`. +- Use square, single-frame PNG or WebP images for token icons. -### TIP-1053: Witness Digest in Key Authorizations +### For key-management and auth flows -[TIP-1053](https://tips.sh/1053) adds an optional `witness: bytes32` field to `key_authorization` so one signature can both authorize an access key and bind to an application challenge. The protocol includes the witness in the signing hash and emits it when the key authorization is registered, but otherwise treats it as opaque and application-defined. In login or delegated-access flows, an app server can derive a 32-byte witness from its challenge, include it in the key authorization, and verify off-chain that the signed authorization is bound to that challenge — collapsing the previous two-prompt flow (one challenge signature, one key-authorization signature) into a single signature without weakening key-authorization semantics. +- Add the optional `witness` field to key-authorization encoding and decoding. +- Include the witness in signing and verification flows. +- Treat the witness as opaque application data. diff --git a/src/pages/quickstart/tokenlist.mdx b/src/pages/quickstart/tokenlist.mdx index 09eb8fb7..f3aa1c05 100644 --- a/src/pages/quickstart/tokenlist.mdx +++ b/src/pages/quickstart/tokenlist.mdx @@ -31,12 +31,6 @@ As an example, here's Tempo's tokenlist, fetched from [tokenlist.tempo.xyz/list/ ## Adding a New Token -:::info[Coming with T5] -The [T5 network upgrade](/protocol/upgrades/t5) introduces an optional on-chain `logoURI` field on every TIP-20 token ([TIP-1026](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1026.md)). After activation, token issuers can publish their official icon directly on the token contract, and any wallet or explorer can render it without going through this registry. Most issuers will still want to register here for richer metadata extensions (`coingeckoId`, `bridgeInfo`, display `label`) and as a fallback icon for clients that don't yet read on-chain `logoURI`. - -Until T5 activates, the registry flow described below is the only path. For the on-chain `logoURI` surface area shipping with T5, see the [Optional logoURI in TIP-20 section of the T5 page](/protocol/upgrades/t5#optional-logouri-in-tip-20-tip-1026). -::: - 1. **Fork** [tempoxyz/tempo-apps](https://github.com/tempoxyz/tempo-apps) 2. **Add token** to `data//tokenlist.json` in `apps/tokenlist`: @@ -56,6 +50,8 @@ Until T5 activates, the registry flow described below is the only path. For the 3. **Add icon** to `data//icons/
.svg` (lowercase address) in `apps/tokenlist` + Separately, TIP-20 tokens can also carry an optional on-chain `logoURI` ([TIP-1026](https://tips.sh/1026)) that wallets and explorers read directly from the token contract. Because that icon is fetched from an untrusted source, TIP-1026 recommends a square, rasterized PNG or WebP (max 256 bytes; `https`, `http`, `ipfs`, or `data` scheme). Setting it is optional and independent of this PR — registering here still adds richer metadata (`coingeckoId`, `bridgeInfo`, display `label`) and a fallback icon for clients that don't read on-chain `logoURI`. + 4. **Submit PR** with as much information as you think is helpful for review. @@ -100,10 +96,10 @@ For **native tokens** (e.g., PathUSD), omit `bridgeInfo`: - Format: SVG - Address filename must be lowercase (e.g., `0xabcd...1234.svg`) -- Recommended: square aspect ratio, minimal whitespace 1Code has comments. Press enter to view. +- Recommended: square aspect ratio, minimal whitespace -A token that gets added to the tokenlist will atuomatically reflect in the Explorer in the next deployment. +A token that gets added to the tokenlist will automatically reflect in the Explorer in the next deployment. -[Full OpenAPI Spec →](https://tokenlist.tempo.xyz/docs) \ No newline at end of file +[Full OpenAPI Spec →](https://tokenlist.tempo.xyz/docs)