From 16dd61837437fa352d4c598c1a6f0cf686d327fb Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Sat, 3 Jan 2026 13:22:52 +0100 Subject: [PATCH 01/11] initial empty advisory.md --- standards/ICRC-2/ADVISORY.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 standards/ICRC-2/ADVISORY.md diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md new file mode 100644 index 00000000..e69de29b From 1abc1994fbbb0d4c57305087299d3e82f7db3a87 Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Sat, 3 Jan 2026 13:24:28 +0100 Subject: [PATCH 02/11] advisory on deduplication --- standards/ICRC-2/ADVISORY.md | 57 ++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index e69de29b..95a5b6e0 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -0,0 +1,57 @@ +# ICRC-2 Advisory + +This document provides clarifications and implementation guidance for the +ICRC-2 standard based on findings from a security review. + +The intent of this advisory is to make explicit certain behaviors that are +underspecified in the ICRC-2 specification, in order to reduce ambiguity for +ledger implementers and client developers. This document does not change the +normative requirements of ICRC-2, but clarifies expectations and highlights +recommended practices. + +--- + +## 1. Transaction Deduplication + +### Clarification + +ICRC-2 methods (`approve` and `transfer_from`) include arguments and error +variants (`created_at_time`, `memo`, `Duplicate`, `TooOld`) that imply support +for transaction deduplication and replay protection. + +This advisory clarifies the expected deduplication behavior for ICRC-2 +operations. + +### Advisory Guidance + +Ledger implementations SHOULD implement transaction deduplication for +`approve` and `transfer_from` according to the following rules: + +#### Transaction Identity + +- A transaction is identified by the combination of: + - the caller, + - the method name (`approve` or `transfer_from`), + - the full set of method arguments, including `created_at_time` and `memo` + if provided. + +- Two calls with identical transaction identity are considered duplicates. + +#### Time Window + +- If `created_at_time` is provided: + - The ledger SHOULD reject calls whose `created_at_time` is too far in the + past or too far in the future relative to the ledger’s current time, + returning a `TooOld` error. + - The ledger SHOULD define and document the accepted time window. + +- If `created_at_time` is not provided: + - The ledger MAY treat each call as unique, or + - MAY apply ledger-specific policies; such behavior SHOULD be documented. + +#### Duplicate Handling + +- If a call is determined to be a duplicate of a previously processed + transaction: + - The ledger SHOULD reject the call and return a `Duplicate` error. + - The ledger MUST NOT apply the transaction effects again. From ef883d5ec354720dcb8c5fc5dc9dee416f66296f Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Sat, 3 Jan 2026 13:27:18 +0100 Subject: [PATCH 03/11] stage changes & client considerations --- standards/ICRC-2/ADVISORY.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index 95a5b6e0..3672f00f 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -55,3 +55,30 @@ Ledger implementations SHOULD implement transaction deduplication for transaction: - The ledger SHOULD reject the call and return a `Duplicate` error. - The ledger MUST NOT apply the transaction effects again. + + + +#### State Changes and Ordering + +- Deduplication checks SHOULD be performed before any externally observable + ledger effects are applied. +- `Duplicate` or `TooOld` responses SHOULD imply that no balances, allowances, + or transaction log entries have been modified. + +#### Interaction with `expected_allowance` + +- For `approve`, the `expected_allowance` field provides an additional + conditional update mechanism. +- `expected_allowance` does not replace transaction deduplication and SHOULD + be evaluated only after deduplication checks have passed. + +### Client Considerations + +- When transaction deduplication is implemented as described above, + **retrying an ICRC-2 call with identical parameters is safe** and will not + result in duplicated ledger effects. +- Clients MAY rely on this behavior to safely retry requests in the presence + of timeouts, transient failures, or uncertain outcomes. +- Clients SHOULD still be prepared to handle `Duplicate` and `TooOld` errors + and SHOULD avoid modifying parameters when retrying unless a new + transaction is intended. From ef74c58b9d97c444c8b766c82968708730309013 Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Sat, 3 Jan 2026 13:47:10 +0100 Subject: [PATCH 04/11] error ==> no ledger/balances changes; any change ==> Ok() --- standards/ICRC-2/ADVISORY.md | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index 3672f00f..abb8b40f 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -82,3 +82,47 @@ Ledger implementations SHOULD implement transaction deduplication for - Clients SHOULD still be prepared to handle `Duplicate` and `TooOld` errors and SHOULD avoid modifying parameters when retrying unless a new transaction is intended. + + + +## 2. Error Semantics and Atomicity + +### Clarification + +The ICRC-2 specification does not explicitly state that `approve` and +`transfer_from` are atomic operations, nor does it clearly define which ledger +effects are guaranteed not to occur when an error is returned. + +With the exception of `AllowanceChanged`, which explicitly states that no +allowance update has occurred, the semantics of other error variants are not +specified. + +### Advisory Guidance + +To align with common ledger expectations and reduce ambiguity: + +- Ledger implementations SHOULD ensure that `approve` and `transfer_from` + operations are atomic with respect to **externally observable ledger + effects**, such as: + - account balances, + - allowances, + - and the transaction log. + +- If an ICRC-2 method successfully applies such effects, the ledger SHOULD + return a success response (`Ok(nat)`). + +- If an error response is returned, the ledger SHOULD ensure that: + - no balances or allowances have been modified, and + - no transaction log entry corresponding to the call has been recorded. + +This guidance does not restrict ledgers from mutating internal or auxiliary +state (e.g., caches, metrics, rate limits, or bookkeeping data) when handling +a call that results in an error. + +Additionally: + +- Ledger implementations SHOULD document the meaning of each error variant. +- Client implementations SHOULD NOT assume stronger guarantees than those + described above unless explicitly documented by the ledger. + + From 14b5b185dffde4124a2cea1d8eec0cca0c5cfea5 Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Sat, 3 Jan 2026 14:04:30 +0100 Subject: [PATCH 05/11] section on fees --- standards/ICRC-2/ADVISORY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index abb8b40f..ea6b7faf 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -125,4 +125,22 @@ Additionally: - Client implementations SHOULD NOT assume stronger guarantees than those described above unless explicitly documented by the ledger. +## 3. Fees for `approve` and `transfer_from` + +### Clarification + +The ICRC-2 specification does not explicitly state the fees charged for +`approve` or `transfer_from`. + +This advisory clarifies that these operations are expected to be charged +the same fee returned by the `icrc1_fee` method. + +### Advisory Guidance + +- Ledger implementations SHOULD charge the fee returned by `icrc1_fee` for + both `approve` and `transfer_from`. +- Clients MAY assume that the applicable fee for ICRC-2 operations is the + value returned by `icrc1_fee`. +- Fees SHOULD only be charged when the operation succeeds. +- The fee SHOULD be applied in a manner consistent with ICRC-1 transfers. From 0bae797184fdbcd59b29a927a8104d1d07e2de82 Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Sat, 3 Jan 2026 14:07:42 +0100 Subject: [PATCH 06/11] removed security review references, as irrelevant --- standards/ICRC-2/ADVISORY.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index ea6b7faf..470bdb8c 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -1,7 +1,7 @@ # ICRC-2 Advisory This document provides clarifications and implementation guidance for the -ICRC-2 standard based on findings from a security review. +ICRC-2 standard. The intent of this advisory is to make explicit certain behaviors that are underspecified in the ICRC-2 specification, in order to reduce ambiguity for @@ -9,7 +9,6 @@ ledger implementers and client developers. This document does not change the normative requirements of ICRC-2, but clarifies expectations and highlights recommended practices. ---- ## 1. Transaction Deduplication From db81fa331d64f7c55eb11046f82b81a080433c1f Mon Sep 17 00:00:00 2001 From: bogwar <51327868+bogwar@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:16:54 +0100 Subject: [PATCH 07/11] Update standards/ICRC-2/ADVISORY.md Co-authored-by: tmu0 <108675202+tmu0@users.noreply.github.com> --- standards/ICRC-2/ADVISORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index 470bdb8c..9e10ed60 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -45,7 +45,7 @@ Ledger implementations SHOULD implement transaction deduplication for - The ledger SHOULD define and document the accepted time window. - If `created_at_time` is not provided: - - The ledger MAY treat each call as unique, or + - The ledger MAY process duplicates, or - MAY apply ledger-specific policies; such behavior SHOULD be documented. #### Duplicate Handling From e9e87c73dfb2531b4a96a8f70f9972e24ebb9d43 Mon Sep 17 00:00:00 2001 From: bogwar <51327868+bogwar@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:19:06 +0100 Subject: [PATCH 08/11] Apply suggestions from code review Co-authored-by: tmu0 <108675202+tmu0@users.noreply.github.com> --- standards/ICRC-2/ADVISORY.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index 9e10ed60..949f4368 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -41,8 +41,9 @@ Ledger implementations SHOULD implement transaction deduplication for - If `created_at_time` is provided: - The ledger SHOULD reject calls whose `created_at_time` is too far in the past or too far in the future relative to the ledger’s current time, - returning a `TooOld` error. + returning a `TooOld`/`CreatedInFuture` error. - The ledger SHOULD define and document the accepted time window. + - The ledger SHOULD NOT process duplicates. - If `created_at_time` is not provided: - The ledger MAY process duplicates, or @@ -50,8 +51,7 @@ Ledger implementations SHOULD implement transaction deduplication for #### Duplicate Handling -- If a call is determined to be a duplicate of a previously processed - transaction: +- If duplicate transactions are not processed: - The ledger SHOULD reject the call and return a `Duplicate` error. - The ledger MUST NOT apply the transaction effects again. @@ -61,7 +61,7 @@ Ledger implementations SHOULD implement transaction deduplication for - Deduplication checks SHOULD be performed before any externally observable ledger effects are applied. -- `Duplicate` or `TooOld` responses SHOULD imply that no balances, allowances, +- `Duplicate`, `TooOld` or `CreatedInFuture` responses SHOULD imply that no balances, allowances, or transaction log entries have been modified. #### Interaction with `expected_allowance` @@ -73,12 +73,12 @@ Ledger implementations SHOULD implement transaction deduplication for ### Client Considerations -- When transaction deduplication is implemented as described above, +- When the ledger does not process duplicate transactions, **retrying an ICRC-2 call with identical parameters is safe** and will not result in duplicated ledger effects. - Clients MAY rely on this behavior to safely retry requests in the presence of timeouts, transient failures, or uncertain outcomes. -- Clients SHOULD still be prepared to handle `Duplicate` and `TooOld` errors +- Clients SHOULD still be prepared to handle `Duplicate`/`TooOld`/`CreatedInFuture` errors and SHOULD avoid modifying parameters when retrying unless a new transaction is intended. From 575b6fcf491530a51df58db7094e3373ec5ea070 Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Wed, 7 Jan 2026 10:23:18 +0100 Subject: [PATCH 09/11] added icrc2 prefix to methods --- standards/ICRC-2/ADVISORY.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/standards/ICRC-2/ADVISORY.md b/standards/ICRC-2/ADVISORY.md index 949f4368..00a40bbd 100644 --- a/standards/ICRC-2/ADVISORY.md +++ b/standards/ICRC-2/ADVISORY.md @@ -14,7 +14,7 @@ recommended practices. ### Clarification -ICRC-2 methods (`approve` and `transfer_from`) include arguments and error +ICRC-2 methods (`icrc2_approve` and `icrc2_transfer_from`) include arguments and error variants (`created_at_time`, `memo`, `Duplicate`, `TooOld`) that imply support for transaction deduplication and replay protection. @@ -24,13 +24,13 @@ operations. ### Advisory Guidance Ledger implementations SHOULD implement transaction deduplication for -`approve` and `transfer_from` according to the following rules: +`icrc2_approve` and `icrc2_transfer_from` according to the following rules: #### Transaction Identity - A transaction is identified by the combination of: - the caller, - - the method name (`approve` or `transfer_from`), + - the method name (`icrc2_approve` or `icrc2_transfer_from`), - the full set of method arguments, including `created_at_time` and `memo` if provided. @@ -66,7 +66,7 @@ Ledger implementations SHOULD implement transaction deduplication for #### Interaction with `expected_allowance` -- For `approve`, the `expected_allowance` field provides an additional +- For `icrc2_approve`, the `expected_allowance` field provides an additional conditional update mechanism. - `expected_allowance` does not replace transaction deduplication and SHOULD be evaluated only after deduplication checks have passed. @@ -88,8 +88,8 @@ Ledger implementations SHOULD implement transaction deduplication for ### Clarification -The ICRC-2 specification does not explicitly state that `approve` and -`transfer_from` are atomic operations, nor does it clearly define which ledger +The ICRC-2 specification does not explicitly state that `icrc2_approve` and +`icrc2_transfer_from` are atomic operations, nor does it clearly define which ledger effects are guaranteed not to occur when an error is returned. With the exception of `AllowanceChanged`, which explicitly states that no @@ -100,7 +100,7 @@ specified. To align with common ledger expectations and reduce ambiguity: -- Ledger implementations SHOULD ensure that `approve` and `transfer_from` +- Ledger implementations SHOULD ensure that `icrc2_approve` and `icrc2_transfer_from` operations are atomic with respect to **externally observable ledger effects**, such as: - account balances, @@ -124,12 +124,12 @@ Additionally: - Client implementations SHOULD NOT assume stronger guarantees than those described above unless explicitly documented by the ledger. -## 3. Fees for `approve` and `transfer_from` +## 3. Fees for `icrc2_approve` and `icrc2_transfer_from` ### Clarification The ICRC-2 specification does not explicitly state the fees charged for -`approve` or `transfer_from`. +`icrc2_approve` or `icrc2_transfer_from`. This advisory clarifies that these operations are expected to be charged the same fee returned by the `icrc1_fee` method. @@ -137,7 +137,7 @@ the same fee returned by the `icrc1_fee` method. ### Advisory Guidance - Ledger implementations SHOULD charge the fee returned by `icrc1_fee` for - both `approve` and `transfer_from`. + both `icrc2_approve` and `icrc2_transfer_from`. - Clients MAY assume that the applicable fee for ICRC-2 operations is the value returned by `icrc1_fee`. - Fees SHOULD only be charged when the operation succeeds. From 68214e8001fc41cd550894f8f8244cba5f6ab013 Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Wed, 7 Jan 2026 10:37:57 +0100 Subject: [PATCH 10/11] advisory for ICRC-1 --- standards/ICRC-1/ADVISORY.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 standards/ICRC-1/ADVISORY.md diff --git a/standards/ICRC-1/ADVISORY.md b/standards/ICRC-1/ADVISORY.md new file mode 100644 index 00000000..e69de29b From 285532317cb586185278a7d9d7d3a7ed5b7861c3 Mon Sep 17 00:00:00 2001 From: Bogdan Warinschi Date: Wed, 7 Jan 2026 10:39:08 +0100 Subject: [PATCH 11/11] parallel text to the one for ICRC-2 --- standards/ICRC-1/ADVISORY.md | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/standards/ICRC-1/ADVISORY.md b/standards/ICRC-1/ADVISORY.md index e69de29b..bcf999ae 100644 --- a/standards/ICRC-1/ADVISORY.md +++ b/standards/ICRC-1/ADVISORY.md @@ -0,0 +1,58 @@ +# ICRC-1 Advisory + +This document provides clarifications and implementation guidance for the +ICRC-1 standard. + +It focuses on error handling and atomicity for `icrc1_transfer`. This +advisory is non-normative and does not change the ICRC-1 specification. + + +## Error Semantics and Atomicity + +### Clarification + +The ICRC-1 specification defines error variants for `icrc1_transfer`, but +does not explicitly state which ledger effects are guaranteed not to occur +when an error is returned. + +This advisory clarifies the expected behavior. + +### Advisory Guidance + +Ledger implementations SHOULD ensure that `icrc1_transfer` is atomic with +respect to **externally observable ledger effects**, including: + +- account balances, and +- the transaction log. + +In particular: + +- A successful response (`Ok(nat)`) SHOULD imply that all balance updates and + the corresponding transaction log entry have been applied. + +- An error response SHOULD imply that: + - no account balances have been modified, and + - no transaction log entry corresponding to the call has been recorded. + +This guidance does not restrict changes to internal or auxiliary ledger +state (e.g., caches, metrics, bookkeeping data). + +### Client Considerations + +- Clients MAY assume that an error response from `icrc1_transfer` implies no + externally observable ledger effects. +- Clients SHOULD NOT assume stronger guarantees unless explicitly documented + by the ledger. + +## Scope and Non-Goals + +This advisory does not modify the ICRC-1 interface, define new error types, or +constrain internal ledger state. + + +## Summary + +ICRC-1 transfers are expected to be atomic with respect to balances and the +transaction log, and error responses should not result in partial externally +observable effects. +