diff --git a/axelar-chains-config/info/mainnet.json b/axelar-chains-config/info/mainnet.json index 48c475dd7..e6998b3d4 100644 --- a/axelar-chains-config/info/mainnet.json +++ b/axelar-chains-config/info/mainnet.json @@ -2929,7 +2929,7 @@ "InterchainTokenService": { "address": "CBDBMIOFHGWUFRYH3D3STI2DHBOWGDDBCRKQEUB4RGQEBVG74SEED6C6", "deployer": "GC2SJ4YXCMP2LYXMXBNJMK6SNK4XUR7TGJXY4GA3VACNMCZVCQ6VFGG3", - "wasmHash": "827225d8911a0034b6059f6279453b8d6a09a9510b061026bdcbdbe19f918d0d", + "wasmHash": "99a5c6748fc650f81236d05516dfe7ca6b396726851a40107cfef6c691269736", "initializeArgs": { "owner": "GC2SJ4YXCMP2LYXMXBNJMK6SNK4XUR7TGJXY4GA3VACNMCZVCQ6VFGG3", "operator": "GC2SJ4YXCMP2LYXMXBNJMK6SNK4XUR7TGJXY4GA3VACNMCZVCQ6VFGG3", @@ -2941,7 +2941,7 @@ "interchainTokenWasmHash": "85693704d656eb99af464d553a0a8d99b62d039223e72e86b98655def0d345ca", "tokenManagerWasmHash": "4164f47872741793bc682f6fb124623c6c1eb64e342b73319c11d05c2e0e39b0" }, - "version": "1.4.1" + "version": "2.1.0" }, "Multicall": { "address": "CC5LVKQA73ZVVUBAOCV5INV4TXPMELBFJ6XTQUBJTP4O2LSUKAA7VHLZ", diff --git a/axelar-chains-config/info/testnet.json b/axelar-chains-config/info/testnet.json index 98285ee3f..f797dd004 100644 --- a/axelar-chains-config/info/testnet.json +++ b/axelar-chains-config/info/testnet.json @@ -3402,8 +3402,8 @@ "AxelarGateway": { "address": "CB2JYOOZPHO43R57TC5PXV22QICKIDC5NKRF62BZG2J6JYFUIQPIAYY3", "deployer": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", - "wasmHash": "715eb94b616c7271bc1aeaf131f92f3ace830d93c3975e871db9a66951c5de92", - "version": "1.1.2", + "wasmHash": "22be1e7c20c894994eca80496eee819d9a459c275410ffa8c75c645b50ceb4f5", + "version": "2.0.1", "connectionType": "amplifier", "initializeArgs": { "owner": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", @@ -3428,8 +3428,8 @@ "AxelarOperators": { "address": "CBFT33DV6VHT5QQYZWMCIYD6WBCGVN27HAXJ64VWWFXK2MDUSZN4MJPO", "deployer": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", - "wasmHash": "bb0b653d32134aa5f68607f33d38e4f173a3fe5f10d3227f7bf655ee02ad7ca8", - "version": "1.1.2", + "wasmHash": "b5e3c6f27c7ca8c2f3f7d4a7606b28cf879a0c85dc3bbfb8627f63a17e0b3171", + "version": "1.1.4", "initializeArgs": { "owner": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L" } @@ -3437,8 +3437,8 @@ "AxelarGasService": { "address": "CCLZOCGHHC6F6JCZHEUP53LDQHRBPPCNRYXOVFZFS3O63OGRC47CKCGV", "deployer": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", - "wasmHash": "99f9a082d1ac65e4499cb462f7f92912a4715c84fc4e488802126d6c684c7f34", - "version": "1.1.2", + "wasmHash": "5427cbb79c858066cd715769e2f0025784aeaedfc0331feae74c82668caf4e78", + "version": "2.0.1", "initializeArgs": { "owner": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", "operator": "CBFT33DV6VHT5QQYZWMCIYD6WBCGVN27HAXJ64VWWFXK2MDUSZN4MJPO" @@ -3465,8 +3465,8 @@ "InterchainTokenService": { "address": "CC7LAC4S7KAPIM26WKWFSOXWLNLSG7EXTC2EVY2H2UPKSTX3Z2A7M5YP", "deployer": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", - "wasmHash": "827225d8911a0034b6059f6279453b8d6a09a9510b061026bdcbdbe19f918d0d", - "version": "1.4.1", + "wasmHash": "99a5c6748fc650f81236d05516dfe7ca6b396726851a40107cfef6c691269736", + "version": "2.1.0", "initializeArgs": { "owner": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", "operator": "GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L", diff --git a/releases/stellar/2026-06-ITS-2.1.0.md b/releases/stellar/2026-06-ITS-2.1.0.md new file mode 100644 index 000000000..ebef08c6d --- /dev/null +++ b/releases/stellar/2026-06-ITS-2.1.0.md @@ -0,0 +1,104 @@ +# Stellar ITS v2.1.0 + +| | **Owner** | +| -------------- | ------------------------------------- | +| **Created By** | @rista404 () | +| **Deployment** | @rista404 () | + +| **Network** | **Deployment Status** | **Date** | +| ------------ | --------------------- | ---------- | +| **Stagenet** | TBD | TBD | +| **Testnet** | Completed | 2026-06-03 | +| **Mainnet** | Completed | 2026-06-04 | + +- [Crates](https://crates.io/crates/stellar-interchain-token-service/2.1.0) +- [Releases](https://github.com/axelarnetwork/axelar-amplifier-stellar/releases/tag/stellar-interchain-token-service-v2.1.0) + +## Background + +This is the v2.1.0 Stellar ITS release which adds a per-token **flow limiter role**. + +The flow limiter role enables: + +- The contract operator can delegate flow-limit management on specific tokens to designated addresses via `add_flow_limiter`, `remove_flow_limiter`, and `transfer_flow_limiter` (all operator-only). +- Multiple flow limiters can be approved per `token_id`; revocation removes only the specified limiter. +- Approved limiters can call `set_flow_limit` for their token alongside the operator. +- `is_flow_limiter(token_id, addr)` view function exposes role membership. + +This brings Stellar ITS in line with the EVM TokenManager's flow-limiter delegation model. + +> **Breaking change (on-chain ABI)**: `set_flow_limit` now requires a leading `caller: Address` argument. The caller must authorize via `require_auth` and must be either the contract operator or an approved flow limiter for the given `token_id`. Integrations calling the old `set_flow_limit(token_id, flow_limit)` form must update to `set_flow_limit(caller, token_id, flow_limit)`. + +## Deployment + +Create an `.env` config. `CHAIN` should be set to `stellar` for mainnet, and `stellar-2026-q1-2` (or current quarterly chain) for testnet. + +```yaml +# Change `PRIVATE_KEY` in `.env` to Stellar +PRIVATE_KEY= +ENV= +CHAIN= +``` + +#### Contract Version Info + +| Contract | **Testnet / Mainnet** | +| ------------------------ | --------------------- | +| `InterchainTokenService` | `2.1.0` | + +1. Verify deployer address + +| Network | `deployer address` | +| ----------- | ---------------------------------------------------------- | +| **Testnet** | `GAFUP3J3M2QNUQZA4ZO744IGCHFKMOCYXR2JQ2UQW65IKWG5OCVTXR3L` | +| **Mainnet** | `GBSXKMKLLR64BGH4FEM5NUM3PFKFSZRLPO4IKEQMMDO3HJZ6S4IXVLGW` | + +2. Upgrade `InterchainTokenService` + +```bash +ts-node stellar/deploy-contract.js upgrade InterchainTokenService --version 2.1.0 +``` + +## Checklist + +The following checks should be performed after the rollout. + +1. Read-only smoke test of a v2.1.0-only entrypoint: + +```bash +ts-node stellar/its.js is-flow-limiter \ + 0x1111111111111111111111111111111111111111111111111111111111111111 \ + GBSXKMKLLR64BGH4FEM5NUM3PFKFSZRLPO4IKEQMMDO3HJZ6S4IXVLGW +# expect: "Is Flow Limiter: false" +``` + +2. End-to-end flow-limiter lifecycle. Requires operator signing for the role-management steps: + +```bash +TOKEN_ID=0x1111111111111111111111111111111111111111111111111111111111111111 + +# Generate an ephemeral limiter identity +stellar keys generate flow-limiter-test --network mainnet +LIMITER=$(stellar keys public-key flow-limiter-test) + +# Operator grants the role +ts-node stellar/its.js add-flow-limiter $TOKEN_ID $LIMITER +ts-node stellar/its.js is-flow-limiter $TOKEN_ID $LIMITER # expect: true + +# Switch PRIVATE_KEY to the limiter and exercise the new auth path +PRIVATE_KEY=$(stellar keys secret flow-limiter-test) \ + ts-node stellar/its.js set-flow-limit $TOKEN_ID 1000 +ts-node stellar/its.js flow-limit $TOKEN_ID # expect: 1000 + +# Clean up (limiter can also clear the limit) +PRIVATE_KEY=$(stellar keys secret flow-limiter-test) \ + ts-node stellar/its.js remove-flow-limit $TOKEN_ID + +# Operator revokes the role +ts-node stellar/its.js remove-flow-limiter $TOKEN_ID $LIMITER + +# Drop the ephemeral identity +stellar keys rm flow-limiter-test +``` + +3. Existing interchain-transfer flow still works (no regression). Run any of the standard Stellar↔EVM transfer smoke tests from previous release docs (e.g. [`2026-01-ITS-1.4.1.md`](./2026-01-ITS-1.4.1.md) §Checklist) to confirm. diff --git a/stellar/utils.ts b/stellar/utils.ts index 6e2fd16cc..b048e926e 100644 --- a/stellar/utils.ts +++ b/stellar/utils.ts @@ -28,9 +28,12 @@ const ASSET_TYPE_NATIVE = 'native'; const AXELAR_R2_BASE_URL = 'https://static.axelar.network'; -const TRANSACTION_TIMEOUT = 30; -const RETRY_WAIT = 1000; // 1 sec -const MAX_RETRIES = 30; +const TRANSACTION_TIMEOUT = 600; // seconds — tx envelope timebound +const RETRY_WAIT = 2000; // ms +// Poll until ~30s past timebound expiry; after that the tx can never land, so it's safe to give up. +// Tying these together avoids the failure mode where the script reports "Transaction failed" on a +// tx that eventually succeeds on-chain because polling stopped before the timebound elapsed. +const MAX_RETRIES = Math.ceil((TRANSACTION_TIMEOUT * 1000) / RETRY_WAIT) + 15; // Ledger extension for authorization operations const LEDGER_EXTENSION_FOR_AUTH = 20;