[{"data":1,"prerenderedAt":119},["ShallowReactive",2],{"blog-archive:all":3},{"categories":4,"articles":13},[5,9],{"name":6,"slug":7,"articleCount":8},"Research","research",16,{"name":10,"slug":11,"articleCount":12},"Product Updates","product-updates",14,{"items":14,"total":116,"page":117,"pageSize":118},[15,28,38,48,58,69,79,89,98,106],{"slug":16,"category":7,"categoryLabel":6,"subcategoryLabel":17,"authorName":18,"title":19,"excerpt":20,"contentHtml":21,"coverUrl":22,"publishedAt":23,"updatedAt":24,"readTime":25,"cover":22,"hasCover":26,"coverAlt":27},"sui-move-security-why-legacy-packages-can-still-put-shared-objects-at-risk-after-an-upgrade-fb5a67","Industry Research","MoveBit","Sui Move Security: Why Legacy Packages Can Still Put Shared Objects at Risk After an Upgrade","Upgrading a Sui Move Package does not automatically disable its previous versions. Each upgrade publishes a new Package ID, while earlier versions remain on-chain. If other modules, routers, or clients continue to call a legacy Package, and multiple versions can modify the same Shared Object, conflicting assumptions about shared state can introduce cross-version vulnerabilities.","\u003Ch1>The BlueMove DEX Exploit: Cross-Version Reserve Desynchronization and LP Inflation\u003C\u002Fh1>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Author:\u003C\u002Fstrong> MoveBit (@MoveBit_)\u003Cbr>\u003Cstrong>Date:\u003C\u002Fstrong> October 21, 2026\u003Cbr>\u003Cstrong>Source:\u003C\u002Fstrong> \u003Ca href=\"https:\u002F\u002Fx.com\u002FMoveBit_\u002Fstatus\u002F2112781636664463510\" rel=\"nofollow\">X Post\u003C\u002Fa>\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>Introduction: Why Upgrading a Package Does Not Eliminate Legacy Security Risks\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Upgrading a Sui Move Package does not automatically disable its previous versions. Each upgrade publishes a new Package ID, while earlier versions remain on-chain. If other modules, routers, or clients continue to call a legacy Package, and multiple versions can modify the same Shared Object, conflicting assumptions about shared state can introduce cross-version vulnerabilities.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">This risk is particularly significant in DeFi protocols. Changes to asset storage, reserve accounting, or business logic can leave legacy execution paths operating under outdated assumptions. When different Package versions modify the same state, individually valid operations can combine to violate the protocol&#39;s accounting invariants and create exploitable discrepancies.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">On July 11, 2026, BlueMove, a DEX in the Sui ecosystem, suffered an exploit. A technical analysis published on the Sui Developer Forum in August identified inconsistent updates to the shared \u003Ccode>reserve_x\u003C\u002Fcode> field across callable Package versions as a key factor. The analysis estimated that approximately 714,000 SUI was drained over roughly 23 minutes, representing a loss of about $528,000 at the time.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>The key takeaway:\u003C\u002Fstrong> securing a Sui upgrade requires verifying every still-callable Package version, not just the latest implementation. All versions must preserve the same set of Shared Object state invariants.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">MoveBit, a flagship sub-brand of BitsLab, examines the incident through the lens of Sui Package versioning, Shared Object security, and Move smart contract auditing. Drawing on publicly available bytecode decompilation and on-chain analysis, this article traces the reserve-accounting flaw, explains how it inflated LP minting and enabled withdrawals, and examines practical approaches to isolating legacy code and migrating state safely.\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp class=\"docx-align-justify\">BlueMove&#39;s original source code has not been publicly released. The technical analysis below is based on publicly available bytecode decompilation and on-chain transaction research. All code snippets are simplified illustrations of the underlying mechanisms, not verbatim reproductions of the project&#39;s source code.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Chr>\n\u003Ch2>1. Sui Package Upgrades: Why Legacy Code Remains Callable\u003C\u002Fh2>\n\u003Ch3>1.1 Each Upgrade Creates a New Package ID\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">Sui Move Packages are immutable on-chain code objects. An upgrade publishes a new Package version rather than modifying the existing version in place.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">A protocol may therefore have multiple deployed versions:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>V1\u003C\u002Fstrong> — Package ID: \u003Ccode>0x...\u003C\u002Fcode> (original)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>V2\u003C\u002Fstrong> — Package ID: \u003Ccode>0x...\u003C\u002Fcode> (upgrade)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>V3\u003C\u002Fstrong> — Package ID: \u003Ccode>0x...\u003C\u002Fcode> (latest)\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Each version has its own Package ID. A transaction invokes the version referenced by its call path. Dependencies that reference an older Package do not automatically switch to the latest version when an upstream Package is upgraded.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Deploying V3 therefore does not, by itself, invalidate V1. If legacy functions remain callable and can access the relevant objects, they may continue to execute.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Reference:\u003C\u002Fstrong> \u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fconcepts\u002Fsui-move-concepts\u002Fpackages\u002Fupgrade\" rel=\"nofollow\">Sui Documentation: Package Versioning\u003C\u002Fa>\u003C\u002Fp>\n\u003Ch3>1.2 Packages Define Logic; Shared Objects Hold State\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">In an automated market maker (AMM), the Package defines swap, liquidity provision, withdrawal, and reserve-update logic. Shared Objects hold the pool&#39;s balances, reserves, and LP supply.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The architecture can be represented as follows:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>┌─────────────────────────────────────────┐\n│              Shared Pool Object          │\n│  ┌─────────────────────────────────┐    │\n│  │ reserve_x \u002F reserve_y           │    │\n│  │ lp_supply                       │    │\n│  │ token_x \u002F token_y (or Escrow)   │    │\n│  └─────────────────────────────────┘    │\n└─────────────────────────────────────────┘\n         ↑                    ↑\n         │                    │\n    ┌────┴────┐          ┌────┴────┐\n    │  V1     │          │  V3     │\n    │ Package │          │ Package │\n    └─────────┘          └─────────┘\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">When multiple Package versions can modify the same Pool, they must preserve consistent state invariants.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Suppose V1 stores assets directly in \u003Ccode>pool.token_x\u003C\u002Fcode>, while V3 moves them into \u003Ccode>EscrowCoinsV2\u003C\u002Fcode>. If both versions update \u003Ccode>reserve_x\u003C\u002Fcode> using different balance sources, the reserve field can become inconsistent with the actual distribution of assets.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Each version may behave as designed in isolation. The vulnerability emerges when their differing assumptions collide on the same Shared Object.\u003C\u002Fp>\n\u003Ch3>1.3 Upgrade Compatibility Does Not Guarantee Business-Logic Consistency\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">Sui&#39;s Package upgrade compatibility rules govern aspects such as public function signatures and struct layouts. Passing these checks does not guarantee that different versions preserve the same business invariants.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For example, V1 may treat \u003Ccode>reserve_x\u003C\u002Fcode> as the Pool&#39;s directly held balance, while V3 treats it as the balance held in Escrow. If both versions can update the same field, its value may no longer have a consistent meaning across the protocol.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">A secure upgrade therefore requires more than checking the latest code. It also requires validating shared-state semantics, business invariants, and execution paths across Package versions.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>2. Root Cause: Two Package Versions Update \u003Ccode>reserve_x\u003C\u002Fcode> Using Different Balances\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Public bytecode analysis identifies two callable Package versions as central to the BlueMove incident.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>V1\u003C\u002Fstrong> stores assets in the Pool&#39;s \u003Ccode>token_x\u003C\u002Fcode> and \u003Ccode>token_y\u003C\u002Fcode> fields.\u003C\u002Fli>\n\u003Cli>The newer version uses \u003Ccode>EscrowCoinsV2\u003C\u002Fcode> for asset storage while continuing to maintain reserve values in shared Pool fields.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>2.1 V1 Reserve-Update Logic\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">The relevant V1 logic can be represented as follows:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Simplified V1 reserve update\nfun update_reserves(pool: &amp;mut Pool) {\n    pool.reserve_x = pool.token_x.value();\n    pool.reserve_y = pool.token_y.value();\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">V1 derives the reserves from the balances held directly in the Pool. After this update, the following invariant holds:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pool.reserve_x == pool.token_x.value()\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">This relationship remains valid as long as subsequent V1 calculations use the same balance source.\u003C\u002Fp>\n\u003Ch3>2.2 Reserve-Update Logic in the Newer Version\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">The newer version derives its reserves from Escrow:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Simplified newer version reserve update\nfun update_reserves(pool: &amp;mut Pool, escrow: &amp;EscrowCoinsV2) {\n    pool.reserve_x = escrow.token_x.value();\n    pool.reserve_y = escrow.token_y.value();\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">This implementation maintains a different invariant:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pool.reserve_x == escrow.token_x.value()\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">The difference is fundamental:\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Version\u003C\u002Fth>\n\u003Cth>Balance Source for \u003Ccode>reserve_x\u003C\u002Fcode>\u003C\u002Fth>\n\u003Cth>Meaning of \u003Ccode>reserve_x\u003C\u002Fcode>\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>V1\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>pool.token_x\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Direct Pool balance\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Newer\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>escrow.token_x\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Escrow balance\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp class=\"docx-align-justify\">When the two balances differ, the versions can write different values into the same field.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The last reserve update can change the meaning of \u003Ccode>reserve_x\u003C\u002Fcode>: V1 treats it as the Pool&#39;s direct balance, while the newer version treats it as the Escrow balance.\u003C\u002Fp>\n\u003Ch3>2.3 Why This Is a Cross-Version Vulnerability\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">Consider the following state:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Escrow balance:       350,000 SUI\nPool direct balance:    7,022 SUI\nShared reserve_x:       7,022 SUI\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">Here, \u003Ccode>reserve_x\u003C\u002Fcode> matches the Pool&#39;s direct balance but is roughly 50 times smaller than the Escrow balance.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">If the newer version uses \u003Ccode>reserve_x\u003C\u002Fcode> as the denominator in its LP minting formula, it can misinterpret the difference between these balances as newly added liquidity.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">V1&#39;s reserve update may be internally consistent, and the newer version&#39;s LP formula may be arithmetically correct. The flaw arises when the newer version interprets a value written under V1&#39;s accounting model as though it represented the Escrow balance.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">This is why cross-version security analysis must cover historical Packages, shared objects, and state transitions across functions rather than focusing exclusively on the latest implementation.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>3. How LP Minting Amplifies the Accounting Flaw\u003C\u002Fh2>\n\u003Ch3>3.1 LP Minting Must Reflect Actual Deposits\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">In a simplified AMM, the amount of LP tokens minted can be expressed as:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>ΔLP = S × (Δx \u002F R_x)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">Where:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>Δx\u003C\u002Fcode> is the amount of assets actually deposited.\u003C\u002Fli>\n\u003Cli>\u003Ccode>S\u003C\u002Fcode> is the LP supply before minting.\u003C\u002Fli>\n\u003Cli>\u003Ccode>R_x\u003C\u002Fcode> is the corresponding reserve under the authoritative accounting model.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Both the deposit amount and the reserve must reflect the same asset state. If \u003Ccode>reserve_x\u003C\u002Fcode> is inconsistent with the actual reserve, the formula can produce an inflated result without any arithmetic overflow.\u003C\u002Fp>\n\u003Ch3>3.2 The BlueMove Flaw: Miscalculating the Deposit Amount\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">The relevant minting logic can be simplified as follows:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Simplified LP minting (newer version)\nfun mint_lp(pool: &amp;mut Pool, deposit_x: u64) -&gt; u64 {\n    let current_x = escrow.token_x.value();  \u002F\u002F Actual Escrow balance\n    let delta = current_x - pool.reserve_x;  \u002F\u002F Assumes reserve_x == previous Escrow\n    let lp_to_mint = pool.lp_supply * delta \u002F pool.reserve_x;\n    \u002F\u002F ...\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">The calculation assumes that \u003Ccode>pool.reserve_x\u003C\u002Fcode> represents the Escrow balance before the deposit.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">If V1 has overwritten \u003Ccode>reserve_x\u003C\u002Fcode> with the Pool&#39;s direct balance, then:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>current_x\u003C\u002Fcode> = Escrow balance\u003C\u002Fli>\n\u003Cli>\u003Ccode>reserve_x\u003C\u002Fcode> = Pool direct balance\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">The expression \u003Ccode>current_x - reserve_x\u003C\u002Fcode> no longer measures the assets deposited in the current transaction. Instead, it includes the historical difference between two separate balances.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The denominator is also too small, further inflating the LP output.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The attacker can therefore exploit inconsistent accounting semantics without triggering an integer overflow.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>4. Numerical Walkthrough: How a Small Deposit Can Produce Excessive LP Shares\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">The following figures illustrate the mechanism described in the public analysis. They are representative values, not a complete historical snapshot of a specific pool.\u003C\u002Fp>\n\u003Ch3>4.1 Initial State\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>Escrow balance:   350,000 SUI\nPool balance:       7,022 SUI\nreserve_x:          7,022 SUI\nLP supply:          1,000\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">A V1 swap updates \u003Ccode>reserve_x\u003C\u002Fcode> to the Pool&#39;s direct balance. Although Escrow holds 350,000 SUI, the newer version uses 7,022 SUI as its reserve baseline.\u003C\u002Fp>\n\u003Ch3>4.2 Step One: Add Liquidity Through the Newer Version\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">The attacker deposits approximately 0.057 SUI into the Escrow used by the newer version, alongside the corresponding amount of the other token.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The updated Escrow balance becomes:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>350,000 + 0.057 = 350,000.057 SUI\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">However, \u003Ccode>reserve_x\u003C\u002Fcode> remains at 7,022 SUI.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Δx (perceived) = 350,000.057 - 7,022 ≈ 342,978 SUI\nΔLP = 1,000 × (342,978 \u002F 7,022) ≈ 48,843 LP tokens\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">A deposit of approximately 0.057 SUI thus produces around 48,843 LP tokens, roughly 48.8 times the existing LP supply.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The problem is the incorrect comparison between Escrow&#39;s balance and the Pool&#39;s direct balance, not an arithmetic overflow.\u003C\u002Fp>\n\u003Ch3>4.3 Step Two: Withdraw Liquidity Through V1\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">According to the public analysis, the attack then calls V1&#39;s \u003Ccode>remove_liquidity\u003C\u002Fcode> function. The legacy withdrawal logic reads the Pool&#39;s direct balance rather than the Escrow balance.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Its calculation can be simplified as follows:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Attacker share = new_lp \u002F total_lp\nWithdrawal = pool.token_x.value() × attacker_share\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">Using the representative figures:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Existing LP supply = 1,000\nNew LP minted      = 48,843\nTotal LP supply    = 49,843\n\nAttacker share = 48,843 \u002F 49,843 ≈ 97.99%\n\nWithdrawal ≈ 7,022 × 0.9799 ≈ 6,881 SUI\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">The attacker can therefore withdraw approximately 6,881 SUI from the Pool&#39;s direct balance.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">These assets come from \u003Ccode>pool.token_x\u003C\u002Fcode>, not directly from the 350,000 SUI held in Escrow. The Escrow balance inflates the LP minting calculation, allowing the attacker to claim a disproportionate share of the Pool&#39;s directly held assets.\u003C\u002Fp>\n\u003Ch3>4.4 Why the Attack Works Within a Single Transaction\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">The public analysis indicates that the attacker used a Programmable Transaction Block (PTB) to call the newer version&#39;s \u003Ccode>add_liquidity_returns\u003C\u002Fcode> function and then V1&#39;s \u003Ccode>remove_liquidity\u003C\u002Fcode> function within the same transaction.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>PTB:\n  1. Call newer.add_liquidity_returns(...) → returns LP tokens\n  2. Call V1.remove_liquidity(LP tokens)   → withdraws from Pool\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">The LP tokens returned by \u003Ccode>add_liquidity_returns\u003C\u002Fcode> can be passed to subsequent commands. This allows the attacker to combine the newer version&#39;s minting logic with the legacy withdrawal logic in a single transaction.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The public analysis describes a transaction containing 49 programmable commands and repeated call sequences across multiple pools. It estimates that approximately 363 pools were affected, with total transfers of around 714,000 SUI.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Source:\u003C\u002Fstrong> \u003Ca href=\"https:\u002F\u002Fforums.sui.io\u002Ft\u002Fbluemove-was-not-an-overflow-bug-how-a-cross-version-reserve-desync-drained-714-000-sui\u002F49409\" rel=\"nofollow\">Sui Developer Forum: BlueMove Cross-Version Reserve Desynchronization Analysis\u003C\u002Fa>\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>5. Why Destroying the UpgradeCap Does Not Disable Legacy Code\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">The public analysis reports that BlueMove&#39;s \u003Ccode>UpgradeCap\u003C\u002Fcode> was destroyed on June 3, 2026, while the exploit occurred on July 11.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Destroying an \u003Ccode>UpgradeCap\u003C\u002Fcode> can permanently prevent further upgrades to a Package. It does not remove historical Packages from the blockchain or invalidate their functions. Legacy code can remain callable through its original Package ID.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Upgrade authorization and legacy-code control are separate security concerns. Preventing further upgrades does not prevent an older version from modifying shared state.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Reference:\u003C\u002Fstrong> \u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fconcepts\u002Fsui-move-concepts\u002Fpackages\u002Fupgrade\" rel=\"nofollow\">Sui Documentation: Upgrading Packages\u003C\u002Fa>\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>6. Remediation: Object Version Checks and Legacy-State Isolation\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">The appropriate remediation depends on whether the protocol incorporated version control into its Shared Object design from the outset.\u003C\u002Fp>\n\u003Ch3>6.1 Approach One: Add Object Version Checks in the Initial Design\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">Sui recommends designing Package version management into systems that interact with Shared Objects.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The following example illustrates a version check:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>const VERSION: u64 = 1;\n\nstruct Pool has key {\n    id: UID,\n    version: u64,\n    \u002F\u002F ... other fields\n}\n\npublic fun swap(pool: &amp;mut Pool, ...) {\n    assert!(pool.version == VERSION, E_WRONG_VERSION);\n    \u002F\u002F ... swap logic\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">When publishing a new version, the module&#39;s \u003Ccode>VERSION\u003C\u002Fcode> can be increased to 2, with a migration function protected by an appropriate capability:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>const VERSION: u64 = 2;\n\npublic fun migrate(pool: &amp;mut Pool, _: &amp;AdminCap) {\n    assert!(pool.version == 1, E_WRONG_VERSION);\n    pool.version = 2;\n    \u002F\u002F ... migrate state if needed\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">These snippets illustrate the mechanism rather than provide a complete implementation. Production code must account for the actual module types, authorization rules, and migration requirements. Passing an \u003Ccode>AdminCap\u003C\u002Fcode> illustrates how a capability object can restrict migration privileges.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">After migration, the Pool&#39;s version becomes 2. A legacy function will abort on a version mismatch only if that version already checks \u003Ccode>pool.version == VERSION\u003C\u002Fcode> at the relevant entry points.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>The critical limitation is that adding a version check to the new Package cannot change the behavior of legacy code that never implemented one.\u003C\u002Fstrong> If V1 lacks the check, adding it to V2 does not disable V1.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Sui also imposes struct-layout compatibility requirements on upgrades. Developers cannot assume that arbitrary fields can be added to an already published struct. Version fields and migration mechanisms should therefore be considered during the initial design.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Reference:\u003C\u002Fstrong> \u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fconcepts\u002Fsui-move-concepts\u002Fpackages\u002Fupgrade\" rel=\"nofollow\">Sui Documentation: Upgrading Packages\u003C\u002Fa>\u003C\u002Fp>\n\u003Ch3>6.2 Approach Two: Introduce a New Object Type When Legacy Code Lacks Version Checks\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">If a deployed legacy version lacks version checks and its behavior cannot be changed through a compatible upgrade, the protocol may need to introduce a new object type and migrate the state into it.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>struct PoolV2 has key {\n    id: UID,\n    \u002F\u002F ... new fields with correct accounting\n}\n\npublic fun migrate_to_v2(old_pool: Pool, _: &amp;AdminCap): PoolV2 {\n    \u002F\u002F Transfer assets, validate balances\n    \u002F\u002F Return new PoolV2\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">The migration process should:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Verify authorization through a protected administrative entry point.\u003C\u002Fli>\n\u003Cli>Transfer assets and required state from the legacy object to the new \u003Ccode>PoolV2\u003C\u002Fcode> object.\u003C\u002Fli>\n\u003Cli>Validate balances, reserves, and LP supply before and after migration.\u003C\u002Fli>\n\u003Cli>Emit migration events recording the relationship between the old and new objects.\u003C\u002Fli>\n\u003Cli>Update routers, SDKs, and other dependencies to use the new object.\u003C\u002Fli>\n\u003Cli>Deprecate the old object and prevent it from being used in normal protocol operations.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp class=\"docx-align-justify\">Creating \u003Ccode>PoolV2\u003C\u002Fcode> alone does not disable the old Package. The protocol must verify that legacy execution paths cannot affect the new authoritative state or leave users exposed to obsolete asset-handling functions.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Sui&#39;s upgrade documentation discusses introducing new types and migration functions when legacy Shared Objects contain flawed logic. The new implementation can then accept only the new object type, breaking the compatibility relationship with the legacy object.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Effective remediation must address Package versions, object types, state migration, and dependent callers together. Adding access controls to the latest version does not change the behavior of historical Packages.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>7. Regression Testing: Verifying the Cross-Version Fix\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Testing should cover interactions between Package versions, not just the latest implementation. The goal is to verify that legacy execution paths cannot violate the protocol&#39;s state invariants.\u003C\u002Fp>\n\u003Ch3>7.1 Ensure Legacy Functions Cannot Operate on Migrated Objects\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">If object version checks are used, test the expected behavior:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Given:\n    Pool.version = 2\n    V1.VERSION = 1\n\nWhen:\n    V1.swap(Pool)\n\nThen:\n    Transaction aborts with E_WRONG_VERSION\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">This test is valid only if V1 already contains the version check. Testing V2 alone cannot prove that legacy code without such a check has been blocked.\u003C\u002Fp>\n\u003Ch3>7.2 Test Cross-Version Call Sequences\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">Test combinations such as:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>V1.swap\u003C\u002Fcode> → \u003Ccode>V2.add_liquidity\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>V2.swap\u003C\u002Fcode> → \u003Ccode>V1.remove_liquidity\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>V1.update\u003C\u002Fcode> → \u003Ccode>V2.mint\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>V2.migrate\u003C\u002Fcode> → \u003Ccode>V1.swap\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Operations that are prohibited by design should abort or fail because of type isolation. Permitted combinations must preserve consistent asset balances, reserves, and LP supply.\u003C\u002Fp>\n\u003Ch3>7.3 Verify LP Minting Against Actual Deposits\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">Construct a test state similar to the one described in the BlueMove analysis:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Escrow balance = 350,000 SUI\nPool balance   =   7,022 SUI\nreserve_x      =   7,022 SUI\nLP supply      =   1,000\nDeposit        =       0.057 SUI\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">When \u003Ccode>reserve_x\u003C\u002Fcode> differs from the authoritative reserve, the protocol should reject unsafe minting or ensure that historical balance differences cannot be counted as newly deposited assets.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Tests should verify the resulting LP amount against the actual deposit and the correct reserve baseline, rather than checking only whether the function executes successfully.\u003C\u002Fp>\n\u003Ch3>7.4 Verify Invariants Before and After Migration\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">For an AMM, regression tests should cover:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Actual asset balances held by the Pool and Escrow.\u003C\u002Fli>\n\u003Cli>Consistency between \u003Ccode>reserve_x\u003C\u002Fcode>, \u003Ccode>reserve_y\u003C\u002Fcode>, and the authoritative asset storage.\u003C\u002Fli>\n\u003Cli>Total LP supply and withdrawal proportions.\u003C\u002Fli>\n\u003Cli>Authorization requirements for migration functions.\u003C\u002Fli>\n\u003Cli>Potential asset loss or duplicate accounting if migration fails.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Tests should include successful and repeated migrations, unauthorized calls, residual legacy objects, and attempts to invoke legacy code after migration.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>8. Conclusion: Upgrade Security Must Cover Every Still-Callable Code Path\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Sui&#39;s immutable Package model allows protocols to evolve while preserving historical code. When multiple versions can still access the same Shared Object, changes to storage structures, reserve calculations, and business rules can leave those versions operating against inconsistent state assumptions.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Addressing this risk requires coordinated Package version management, Shared Object version checks, legacy-object migration, dependency updates, and cross-version regression testing. True upgrade security means verifying that every still-callable Package version preserves the same set of state invariants.\u003C\u002Fp>\n\n\n\u003Cp class=\"docx-align-justify\">BitsLab is a Web3 security company focused on smart contract auditing and security infrastructure for emerging blockchain ecosystems, including Sui, Aptos, Bitcoin, and TON. MoveBit, a flagship sub-brand of BitsLab, specializes in Move ecosystem security, providing smart contract audits and security research for projects building on Sui, Aptos, and other Move-based platforms.\u003C\u002Fp>\n\u003Ch3>Related Resources\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Sui Official Documentation\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fconcepts\u002Fsui-move-concepts\u002Fpackages\u002Fupgrade\" rel=\"nofollow\">Upgrading Packages\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fconcepts\u002Fsui-move-concepts\u002Fpackages\u002Fupgrade\" rel=\"nofollow\">Package Versioning\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fguides\u002Fdeveloper\u002Fsui-101\u002Fsecurity\" rel=\"nofollow\">Security Best Practices\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>MoveBit Research\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fx.com\u002FMoveBit_\u002Fstatus\u002F2109486777723748495\" rel=\"nofollow\">Sui Shared Object Security: How Access Control Flaws Put DeFi Protocols at Risk\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fforums.sui.io\u002Ft\u002Fbluemove-was-not-an-overflow-bug-how-a-cross-version-reserve-desync-drained-714-000-sui\u002F49409\" rel=\"nofollow\">BlueMove Cross-Version Reserve Desynchronization Analysis\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Official Websites\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fmovebit.xyz\u002F\" rel=\"nofollow\">MoveBit\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.bitslab.xyz\u002F\" rel=\"nofollow\">BitsLab\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>","\u002Fmedia\u002Fmovebit\u002F2026\u002F10\u002Fc694b8c5b203afefafc2aefa5bd1a5c1.png","2026-10-22T02:22:49Z","2026-10-22T10:22:49Z","15 min read",true,"Sui Move Security: Why Legacy Packages Can Still Put Shared Objects at Risk After an Upgrade cover image",{"slug":29,"category":7,"categoryLabel":6,"subcategoryLabel":17,"authorName":30,"title":31,"excerpt":32,"contentHtml":33,"coverUrl":34,"publishedAt":35,"updatedAt":36,"readTime":25,"cover":34,"hasCover":26,"coverAlt":37},"sui-shared-object-security-how-access-control-flaws-put-defi-protocols-at-risk-9dc56b","Olivia","Sui Shared Object Security: How Access Control Flaws Put DeFi Protocols at Risk","As an increasing number of DeFi protocols deploy on Sui, Shared Objects have become essential components of liquidity pools, lending markets, and other on-chain financial applications. However, a seemingly simple permission issue can expose an entire protocol's risk parameters to unauthorized calls.","\u003Cp class=\"docx-align-justify\">As an increasing number of DeFi protocols deploy on Sui, Shared Objects have become essential components of liquidity pools, lending markets, and other on-chain financial applications. However, a seemingly simple permission issue can expose an entire protocol&#39;s risk parameters to unauthorized calls.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Suppose a Sui lending protocol stores its liquidation threshold inside a shared \u003Ccode>Market\u003C\u002Fcode> object. Regular users need to access this \u003Ccode>Market\u003C\u002Fcode> object to make deposits, borrows, and repayments, while administrators are responsible for adjusting risk configurations like collateral ratios and liquidation thresholds.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Now, what happens if a regular user can modify the liquidation threshold through a public function?\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">An attacker might not need to compromise an administrator account or bypass Move VM security mechanisms. They only need to find a state-modification path lacking proper authorization checks to alter critical protocol parameters, directly impacting the liquidation conditions of existing positions.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">This represents a key class of issues worth studying in Sui Shared Object Security.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Sui Move provides strong foundational security guarantees through Object Ownership, resource models, and type systems. However, these mechanisms do not automatically determine whether every business operation aligns with a protocol’s intended permission design.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For DeFi protocols containing multiple Pools, Vaults, and Markets, developers must manage even more complex object relationships, Capability scopes, and state transition rules.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">In MoveBit&#39;s (a flagship sub-brand of BitsLab) Sui security research, access control for Shared Objects is a critical direction during security audits. This article uses a simplified lending market case study to analyze how missing access checks create vulnerabilities, what issues can arise in Capability design, and how to verify these risks through testing and security audits.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>1. Why Do Shared Objects Require Dedicated Access Control Considerations?\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Sui utilizes an Object Model to manage on-chain state. Every object possesses a unique identifier, ownership metadata, and versioning. Protocols choose different object ownership models based on operational needs.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Common ownership forms include \u003Cstrong>Address-Owned Objects\u003C\u002Fstrong>, \u003Cstrong>Immutable Objects\u003C\u002Fstrong>, and \u003Cstrong>Shared Objects\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Address-Owned Objects:\u003C\u002Fstrong> Transaction usage rights are constrained by explicit object ownership.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Immutable Objects:\u003C\u002Fstrong> Can be publicly read by anyone but cannot be modified.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Shared Objects:\u003C\u002Fstrong> Allow different users to concurrently reference the same object within transactions and execute operations defined by the Move contract logic governing that object.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Sui&#39;s official documentation explicitly states that any address can submit a transaction referencing a Shared Object; therefore, when privileged operations are involved, the contract itself must execute the corresponding authorization checks.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For DeFi applications, shared access brings clear operational value.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For example, an AMM protocol can use a Shared Object to store liquidity pool reserves, fee configurations, and protocol parameters. Different users can execute transaction functions to interact with the exact same Pool.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>LiquidityPool\n├── Token A Reserve\n├── Token B Reserve\n├── Trading Fee\n└── Protocol Configuration\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">When regular users perform a swap, asset balances within the pool are updated according to protocol rules. However, modifying trading fees, updating pause states, or altering key configurations usually constitute restricted operations.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">While both types of operations may utilize \u003Ccode>&amp;mut LiquidityPool\u003C\u002Fcode>, the authorization requirements they must satisfy are fundamentally different.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">In Sui Move, \u003Ccode>&amp;mut T\u003C\u002Fcode> allows a function to modify data of type \u003Ccode>T\u003C\u002Fcode>, provided it satisfies type and borrowing rules. It does not natively provide admin authentication, nor does it confer arbitrary capabilities upon the caller to modify object fields. Which specific modifications can be executed remains entirely dictated by the module defining the object type and its public functions.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Consequently, security analysis of Shared Objects must look deep into function implementations and authorization relationships between objects.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>2. What Risks Does an Access-Control-Deficient Market Function Present?\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Consider a simplified Sui lending market where the protocol utilizes a shared \u003Ccode>Market\u003C\u002Fcode> object to store liquidation thresholds and other risk parameters:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\">\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F10\u002Fdfd888addf58981b79efc87f2ff0f586.png\" width=\"300\">\u003Cbr>\u003C\u002Fp>\n\n\u003Cp class=\"docx-align-justify\">Under normal conditions, regular users access \u003Ccode>Market\u003C\u002Fcode> to perform borrowing and lending operations, while \u003Ccode>liquidation_threshold\u003C\u002Fcode> should only be modifiable by authorized administrators or governance mechanisms.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Suppose a developer implements the following function:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\">\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F10\u002F829dad6b4d0263aefe6414a8a39ceda0.png\" width=\"300\">\u003Cbr>\u003C\u002Fp>\n\n\u003Cp class=\"docx-align-justify\">This code successfully passes basic type checks and indeed modifies the \u003Ccode>Market\u003C\u002Fcode>&#39;s liquidation threshold.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The critical issue is that \u003Cstrong>this function contains no authorization checks whatsoever\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">A \u003Ccode>public\u003C\u002Fcode> function can be accessed via permitted cross-module calls or Programmable Transaction Block (PTB) invocation paths. If a shared \u003Ccode>Market\u003C\u002Fcode> can be passed as a transaction input, an attacker can supply a mutable reference to the shared \u003Ccode>Market\u003C\u002Fcode> along with an arbitrary \u003Ccode>new_threshold\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">No Move resource safety rules are violated here. The attacker simply uses a legitimately referenced shared object to execute a publicly exposed protocol operation.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Assuming the liquidation threshold uses basis points with an initial value of \u003Ccode>8,000\u003C\u002Fcode> (80%), if an attacker modifies it to \u003Ccode>9,900\u003C\u002Fcode> or another abnormal value, the market&#39;s liquidation conditions will diverge completely from the original design.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The exact consequences depend on the protocol&#39;s parameter validation ranges, health factor calculation methods, and liquidation execution logic. Certain implementations could render high-risk positions temporarily unliquidatable, while others might cause healthy positions to suffer abnormal liquidations.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For this specific example, the confirmed flaw is clear: \u003Cstrong>an unauthorized user can modify critical risk parameters that should have been strictly protected.\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Whether actual financial losses occur depends on further analysis of the protocol&#39;s business logic and economic parameters.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>3. How to Reproduce and Verify This Attack Path\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">When conducting a security analysis on this example, auditors can start with the \u003Ccode>liquidation_threshold\u003C\u002Fcode> field:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Confirm where it is initialized.\u003C\u002Fli>\n\u003Cli>Determine which functions read its value.\u003C\u002Fli>\n\u003Cli>Check if alternative modification paths exist.\u003C\u002Fli>\n\u003Cli>Inspect the visibility and parameters of writing functions to verify if regular users can construct the required object inputs.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp class=\"docx-align-justify\">For the \u003Ccode>update_threshold()\u003C\u002Fcode> function shown above, the potential execution path is direct:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Attacker Transaction\n        ↓\nShared Market Object\n        ↓\nPublic update_threshold()\n        ↓\nNo Authorization Check\n        ↓\nliquidation_threshold Modified\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">Throughout this invocation flow, the function does not request an \u003Ccode>AdminCap\u003C\u002Fcode>, nor does it verify caller identity or any authorization conditions.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">To further verify the vulnerability, developers can use Sui&#39;s official \u003Ccode>test_scenario\u003C\u002Fcode> framework to simulate different transaction senders.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For instance, Account A creates the \u003Ccode>Market\u003C\u002Fcode> and sets it as a Shared Object. Then, the test switches to Account B (which lacks administrative permissions), and Account B attempts to modify the liquidation threshold via the public function.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">The following code demonstrates the key testing logic:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\">\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F10\u002Fc616261635a38f93db7ce987cc33e74a.png\" width=\"300\">\u003Cbr>\u003C\u002Fp>\n\n\u003Cblockquote>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Code Note:\u003C\u002Fstrong> \u003Cem>This test is for instructional purposes, assuming \u003Ccode>create_market()\u003C\u002Fcode> is already implemented in the test package and correctly creates a Shared Market. It demonstrates the vulnerability verification concept and has not been independently compiled.\u003C\u002Fem>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp class=\"docx-align-justify\">In actual testing, if an unauthorized account successfully executes the call and the \u003Ccode>Market\u003C\u002Fcode>&#39;s liquidation threshold is altered upon transaction completion, the unauthorized state modification path is proven to exist.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Next, auditors must evaluate whether this parameter change impacts borrowing limits, position health, or liquidation outcomes. Only by completing business-level validations can the severity and exploitability of the vulnerability be accurately gauged.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">In complex protocols, attack paths might span multiple public functions and modules. For instance, a function might not directly modify the liquidation threshold, but could achieve the same result by updating configuration objects, swapping dependent objects, or invoking functions in other modules.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Therefore, security audits must trace the complete \u003Cstrong>State Transition\u003C\u002Fstrong> path to ensure every path capable of modifying sensitive state is protected by proper authorization.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>4. How to Fix Access Control Issues Using the Capability Pattern\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Sui Move typically manages privileged operations using the \u003Cstrong>Capability Pattern\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">A Capability is an object that represents permission to execute a specific operation. Functions restrict sensitive operations by requiring callers to provide a reference to a specific Capability object.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For our lending market example, we can create an \u003Ccode>AdminCap\u003C\u002Fcode> corresponding to each \u003Ccode>Market\u003C\u002Fcode>, storing the target \u003Ccode>Market\u003C\u002Fcode>&#39;s \u003Ccode>ID\u003C\u002Fcode> inside the Capability itself.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Below is a simplified remediation implementation:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\">\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F10\u002F123edbda76c1a22684eb22a59917dd7e.png\" width=\"300\">\u003Cbr>\u003C\u002Fp>\n\n\u003Cblockquote>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Code Note:\u003C\u002Fstrong> \u003Cem>This example demonstrates object-level authorization core implementation and excludes real lending, liquidation, governance, or permission revocation modules. \u003Ccode>create_market()\u003C\u002Fcode> is designed to allow users to create independent demo markets and does not imply production lending protocols should adopt permissionless market creation. This code has not been independently compiled.\u003C\u002Fem>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp class=\"docx-align-justify\">Compared to the vulnerable version, the updated \u003Ccode>update_threshold()\u003C\u002Fcode> function introduces three critical constraints:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Requires \u003Ccode>&amp;AdminCap\u003C\u002Fcode>:\u003C\u002Fstrong> When the Capability employs proper Address-Owned ownership, Sui&#39;s object ownership model restricts who can pass it as a transaction input.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Validates Market Binding:\u003C\u002Fstrong> \u003Ccode>admin.market_id == object::id(market)\u003C\u002Fcode> verifies the explicit link between the Capability and the \u003Ccode>Market\u003C\u002Fcode>. Even if a caller possesses a valid \u003Ccode>AdminCap\u003C\u002Fcode>, they cannot use it to modify a different \u003Ccode>Market\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Validates Bounds &amp; Emits Events:\u003C\u002Fstrong> Checks the bounds of \u003Ccode>new_threshold\u003C\u002Fcode> and emits a \u003Ccode>ThresholdUpdated\u003C\u002Fcode> event upon success to facilitate off-chain tracking of parameter changes.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cblockquote>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>Crucial Requirement:\u003C\u002Fstrong> During remediation, legacy public functions lacking permission checks \u003Cstrong>must be removed or restricted\u003C\u002Fstrong>. Retaining legacy entry points allows attackers to continue modifying fields through unprotected paths.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Chr>\n\u003Ch3>Key Considerations for Capability Design\u003C\u002Fh3>\n\u003Ch4>1. Ownership of the Capability Itself\u003C\u002Fh4>\n\u003Cp class=\"docx-align-justify\">Suppose a protocol mistakenly sets an \u003Ccode>AdminCap\u003C\u002Fcode> as a Shared Object. If any user can pass references to this shared Capability into privileged functions, the requirement for \u003Ccode>&amp;AdminCap\u003C\u002Fcode> fails to enforce admin access controls.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">A Capability&#39;s effectiveness depends entirely on its type, ownership model, and usage restrictions enforced within contract logic. Permissions meant for a single administrator or governance body must use controlled ownership or vault structures to prevent unauthorized access.\u003C\u002Fp>\n\u003Ch4>2. Association Between Capability and Target Objects\u003C\u002Fh4>\n\u003Cp class=\"docx-align-justify\">In multi-market, multi-pool, or multi-vault protocols, verifying the Capability type alone is insufficient.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">If \u003Ccode>Market A\u003C\u002Fcode> and \u003Ccode>Market B\u003C\u002Fcode> both accept the same \u003Ccode>AdminCap\u003C\u002Fcode> type without ID validation, a user holding management rights over \u003Ccode>Market A\u003C\u002Fcode> could illegally manage \u003Ccode>Market B\u003C\u002Fcode>. Binding \u003Ccode>market_id\u003C\u002Fcode> as shown in the example provides baseline protection against cross-object unauthorized calls.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Production protocols should also validate Capability versions, protocol instance IDs, permission roles, and governance states.\u003C\u002Fp>\n\u003Ch4>3. Creation, Transfer, and Revocation Lifecycle\u003C\u002Fh4>\n\u003Cp class=\"docx-align-justify\">Once created, a Capability becomes a critical asset within a protocol&#39;s privilege architecture.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Audits must confirm that Capabilities cannot be duplicated, misallocated, accidentally transferred, or retained after admin handovers.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">When permissions are compromised, protocols must be capable of rejecting compromised Capabilities. Recommended Sui practices include:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Valid Capability ID registries\u003C\u002Fli>\n\u003Cli>Version control\u003C\u002Fli>\n\u003Cli>Epoch-based expiration checks\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Relying solely on compromised holders to voluntarily destroy capabilities is insufficient for revocation.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Additionally, if a protocol supports upgrades, auditors must review \u003Ccode>UpgradeCap\u003C\u002Fcode> holders and upgrade policies. Even if current implementations enforce strict checks, future code upgrades could alter these rules.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Capability security must cover the complete lifecycle: \u003Cstrong>Creation $\\rightarrow$ Possession $\\rightarrow$ Usage $\\rightarrow$ Transfer $\\rightarrow$ Revocation $\\rightarrow$ Upgrade.\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>5. How to Verify That Fixes Are Effective\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">After introducing Capability checks, security tests must be updated accordingly:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Positive Validation:\u003C\u002Fstrong> Authorized administrators can successfully modify their assigned \u003Ccode>Market\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Negative Validation:\u003C\u002Fstrong> Unauthorized users fail when attempting the same operations.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Cross-Capability Testing:\u003C\u002Fstrong> Multi-market protocols must test scenarios involving mismatched Capabilities (e.g., attempting to update \u003Ccode>Market A\u003C\u002Fcode> using \u003Ccode>Market B\u003C\u002Fcode>&#39;s \u003Ccode>AdminCap\u003C\u002Fcode>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Under the updated logic, mismatched operations must fail due to Object ID validation errors. The core test assertion is:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>assert!(\n    admin.market_id == object::id(market),\n    EWrongMarket\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">In unit tests, developers can use \u003Ccode>#[expected_failure]\u003C\u002Fcode> to confirm that \u003Ccode>EWrongMarket\u003C\u002Fcode> is raised as intended.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">It is important to distinguish between two failure types:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Logic Failure:\u003C\u002Fstrong> Supplying a valid Capability belonging to another \u003Ccode>Market\u003C\u002Fcode> triggers contract-internal assertion failures.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Ownership Failure:\u003C\u002Fstrong> Failing to possess an Address-Owned \u003Ccode>AdminCap\u003C\u002Fcode> causes rejection during Sui transaction input validation before Move function execution starts.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Both failure types require testing, though their verification methods differ.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Additionally, development teams must audit all functions capable of writing to \u003Ccode>liquidation_threshold\u003C\u002Fcode>. If \u003Ccode>update_threshold()\u003C\u002Fcode> is secured but a public \u003Ccode>update_config()\u003C\u002Fcode> function still allows unrestricted modifications to the same field, the risk remains unresolved.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For production lending protocols, verification should span three levels:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Permission Testing:\u003C\u002Fstrong> Ensure every sensitive operation has explicit authorization checks, and test mismatched objects, cross-instance Capabilities, and alternative invocation paths.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Parameter Constraint Testing:\u003C\u002Fstrong> Validate that risk parameters (liquidation thresholds, fees, collateral ratios) can only be modified within strictly defined ranges.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Protocol Behavior Testing:\u003C\u002Fstrong> Verify that post-modification borrow, repayment, and liquidation operations adhere to expected economic constraints.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp class=\"docx-align-justify\">Sui&#39;s CLI tool supports running unit tests via \u003Ccode>sui move test\u003C\u002Fcode>, while \u003Ccode>test_scenario\u003C\u002Fcode> enables simulation of multi-sender transactions, object transfers, and shared object interactions:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>sui move test\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp class=\"docx-align-justify\">Prior to mainnet deployment, protocols should validate operations across local networks, Testnet, and real transaction constructs to ensure contract logic behaves as expected within the live Sui execution environment.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For production protocols, comprehensive confidence in remediation effectiveness requires code reviews, permission testing, and business logic verification working in unison across all critical state transitions.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>6. How MoveBit Analyzes Permission Risks in Complex Sui Protocols\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">The previous example featured a single \u003Ccode>Market\u003C\u002Fcode> and one \u003Ccode>AdminCap\u003C\u002Fcode>, making attack paths straightforward to trace. However, real-world Sui DeFi protocols feature far more complex object topologies.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">A lending market may simultaneously depend on \u003Ccode>Pool\u003C\u002Fcode>, \u003Ccode>Vault\u003C\u002Fcode>, \u003Ccode>Position\u003C\u002Fcode>, \u003Ccode>Oracle\u003C\u002Fcode>, \u003Ccode>Treasury\u003C\u002Fcode>, and \u003Ccode>Governance\u003C\u002Fcode> objects. Logic is distributed across multiple modules, with state managed dynamically via Dynamic Fields.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">In these environments, simply checking if a function accepts an \u003Ccode>AdminCap\u003C\u002Fcode> parameter is insufficient to assess overall authorization security.\u003C\u002Fp>\n\u003Ch3>1. Starting from Object Relationships\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">MoveBit&#39;s \u003Cstrong>Sui Smart Contract Audit\u003C\u002Fstrong> builds state and authorization maps around a protocol&#39;s Object Model to identify:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Shared objects vs. private objects.\u003C\u002Fli>\n\u003Cli>Objects holding critical assets or risk configurations.\u003C\u002Fli>\n\u003Cli>Mappings between Capabilities and target objects.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">For example, a lending liquidation process involves user \u003Ccode>Position\u003C\u002Fcode>s, shared \u003Ccode>Market\u003C\u002Fcode>s, \u003Ccode>Oracle\u003C\u002Fcode> prices, and liquidation parameters. Auditors verify that these objects belong to the expected protocol instance, check for cross-market object mixing, and ensure states cannot be modified through unauthorized calls.\u003C\u002Fp>\n\u003Ch3>2. Tracing Authorization Logic Along Execution Paths\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">The second step involves mapping all public functions capable of modifying sensitive fields alongside their invocation hierarchies.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For \u003Ccode>Market.liquidation_threshold\u003C\u002Fcode>, auditors identify every potential write path and evaluate its authorization controls. If a function relies on \u003Ccode>tx_context::sender()\u003C\u002Fcode>, auditors check whether business rules strictly require transaction-sender-based checks. Where permissions are represented via Capabilities, governance objects, or escrow patterns, auditors evaluate ownership conditions and authorization boundaries.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">In protocols with extensive cross-module interactions, special focus is placed on ensuring permissions are not improperly forwarded, escalated, or reused.\u003C\u002Fp>\n\u003Ch3>3. Combining State Transition Analysis with Practical Verification\u003C\u002Fh3>\n\u003Cp class=\"docx-align-justify\">Final risk determinations rest on state modification outcomes:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Can an execution path successfully alter the liquidation threshold?\u003C\u002Fli>\n\u003Cli>Does the modified parameter impact active positions?\u003C\u002Fli>\n\u003Cli>Can an attacker leverage the modified state to execute unauthorized borrows, withdrawals, or liquidations?\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Answering these questions requires analyzing code execution paths, object relationships, and business logic while verifying findings through concrete PoC tests.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For large-scale Move protocols with complex object relationships, AI-assisted analysis can provide valuable support.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">BitsLab developed \u003Cstrong>BitsLab AI\u003C\u002Fstrong>, focusing on \u003Cem>Logic Reasoning\u003C\u002Fem>, \u003Cem>Evidence Chains\u003C\u002Fem>, and \u003Cem>PoC Verification\u003C\u002Fem>. It combines code logic understanding, risk path analysis, and vulnerability verification.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Starting from sensitive state fields, it traces related functions and permission checks, flags potential unauthorized modification paths, and uses automated testing to confirm exploitability.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">This methodology helps auditors systematically organize suspicious paths and verification evidence. While AI provides analytical leads for complex cross-module and multi-object interactions, final conclusions must always be verified against Sui Object Ownership rules, Capability holding conditions, and Move VM execution mechanics.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">MoveBit brings extensive security experience across the Sui ecosystem. In Sui&#39;s June 2025 ecosystem security review, \u003Cem>&#34;Greater Ecosystem Security Through Audits and Move Registry&#34;\u003C\u002Fem>, MoveBit was recognized as a key security audit firm within the Sui ecosystem, with special mention of its contributions to formal verification, developer tooling, and security competitions.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">MoveBit&#39;s public audit portfolio includes leading Sui ecosystem projects such as \u003Cstrong>Scallop\u003C\u002Fstrong>, \u003Cstrong>Cetus\u003C\u002Fstrong>, and \u003Cstrong>NAVI Protocol\u003C\u002Fstrong>. These public audit reports help development teams understand real-world audit scopes, code versions, issue classifications, and fix verification processes.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">For complex Sui DeFi applications, security audits must evaluate object ownership, permission design, state transitions, and business rules within a unified execution context to accurately identify potential risks.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>7. Shared Object Security Must Cover the Entire Protocol Lifecycle\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">Shared Object permission issues must be addressed before protocol deployment.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">In lending, trading, and yield protocols, critical states undergo continuous evolution. Projects frequently add new Markets, adjust risk parameters, switch Oracles, or introduce new business modules via Package Upgrades.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">These changes can alter existing authorization dynamics:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Does an \u003Ccode>AdminCap\u003C\u002Fcode> designed for a single market maintain appropriate permission boundaries as the protocol expands?\u003C\u002Fli>\n\u003Cli>Do newly added configuration functions reuse legacy permission checks correctly?\u003C\u002Fli>\n\u003Cli>Does a package upgrade introduce new invocation paths capable of modifying sensitive state?\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp class=\"docx-align-justify\">Every upgrade impacting permissions or critical state requires thorough re-verification.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Sui&#39;s official security guidelines emphasize that smart contract audits must evaluate specific code versions, dependencies, and upgrade authorities. For upgradeable protocols, security guarantees from an earlier audit do not automatically extend to future code modifications.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">Consequently, teams must establish continuous security review processes, complemented by traceable events and monitoring rules for parameter updates and admin operations.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>Conclusion &amp; Next Steps\u003C\u002Fh2>\n\u003Cp class=\"docx-align-justify\">For teams building or upgrading Sui DeFi protocols involving Shared Pools, Markets, Vaults, or complex Capability designs, conducting a comprehensive audit of object relationships, permission checks, and state transitions prior to deployment is highly recommended.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">\u003Cstrong>MoveBit\u003C\u002Fstrong> provides specialized \u003Cstrong>Smart Contract Security Audits\u003C\u002Fstrong> for Sui and Move ecosystem projects, focusing on object ownership, permission logic, state transitions, and protocol business risks to help teams identify and remediate potential security flaws before mainnet deployment.\u003C\u002Fp>\n\u003Cp class=\"docx-align-justify\">If your project is preparing for deployment, upgrading smart contracts, or re-evaluating audit requirements, reach out via the official MoveBit website to discuss your code scope, protocol architecture, and security review needs.\u003C\u002Fp>\u003Ch2>\u003Cspan>Related Resources\u003C\u002Fspan>\u003C\u002Fh2>\u003Ch3>\u003Cspan>Sui Official Documentation\u003C\u002Fspan>\u003C\u002Fh3>\u003Cul>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fdevelop\u002Fwrite-move\u002Fmove-best-practices?utm_source=chatgpt.com\" rel=\"nofollow\">\u003Cspan>Move Best Practices\u003C\u002Fspan>\u003C\u002Fa>\u003Cbr>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fwww.sui.io\u002Fblog\u002Fsecurity-best-practices?utm_source=chatgpt.com\" rel=\"nofollow\">\u003Cspan>Security Best Practices for Building on Sui\u003C\u002Fspan>\u003C\u002Fa>\u003Cbr>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fdevelop\u002Fobjects\u002Fobject-ownership\u002Fshared\" rel=\"nofollow\">\u003Cspan>Shared Objects Documentation\u003C\u002Fspan>\u003C\u002Fa>\u003Cbr>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fdocs.sui.io\u002Fdevelop\u002Ftesting-debugging\u002Ftesting\" rel=\"nofollow\">\u003Cspan>Testing Move Smart Contracts\u003C\u002Fspan>\u003C\u002Fa>\u003Cbr>\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Chr>\u003Ch3>\u003Cspan>MoveBit Research &amp; Audit Resources\u003C\u002Fspan>\u003C\u002Fh3>\u003Cul>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fwww.movebit.xyz\u002F?utm_source=chatgpt.com\" rel=\"nofollow\">\u003Cspan>MoveBit Official Website\u003C\u002Fspan>\u003C\u002Fa>\u003Cbr>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmovebit\u002FSampled-Audit-Reports?utm_source=chatgpt.com\" rel=\"nofollow\">\u003Cspan>\u003Cspan>\u003Cspan>MoveBit Public Audit Reports\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fa>\u003Cbr>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmovebit?utm_source=chatgpt.com\" rel=\"nofollow\">\u003Cspan>\u003Cspan>\u003Cspan>MoveBit GitHub Repository\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fa>\u003Cbr>\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Chr>\u003Ch3>\u003Cspan>BitsLab AI\u003C\u002Fspan>\u003C\u002Fh3>\u003Cul>\u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fwww.movebit.xyz\u002Fblog\u002Fbitslabai-scanner-outperformed-numerous-audit-participants-in-the-competition-securing-second-place?utm_source=chatgpt.com\" rel=\"nofollow\">\u003Cspan>BitsLab AI Scanner: AI-Powered Smart Contract Security Analysis\u003C\u002Fspan>\u003C\u002Fa>\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>","\u002Fmedia\u002Fmovebit\u002F2026\u002F10\u002Fc24af78569a14f376bdc155437a2c0db.png","2026-10-12T07:12:10Z","2026-10-12T15:12:10Z","Sui Shared Object Security: How Access Control Flaws Put DeFi Protocols at Risk cover image",{"slug":39,"category":7,"categoryLabel":6,"subcategoryLabel":17,"authorName":30,"title":40,"excerpt":41,"contentHtml":42,"coverUrl":43,"publishedAt":44,"updatedAt":45,"readTime":46,"cover":43,"hasCover":26,"coverAlt":47},"stable-abi-changing-trust-root-how-the-pyth-core-upgrade-redefines-sui-oracle-security-a30f20","Stable ABI, Changing Trust Root: How the Pyth Core Upgrade Redefines Sui Oracle Security","On August 26, Pyth Core introduced a major infrastructure upgrade. The new architecture preserves compatibility at the Hermes API and on-chain ABI layers, but the underlying verification model changes significantly: the previous path relied on Pythnet and a 13-of-19 Wormhole Guardian signature threshold, while the new design uses five independent routers with a 3-of-5 quorum.","\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">On August 26, Pyth Core introduced a major infrastructure upgrade. The new architecture preserves compatibility at the Hermes API and on-chain ABI layers, but the underlying verification model changes significantly: the previous path relied on Pythnet and a 13-of-19 Wormhole Guardian signature threshold, while the new design uses five independent routers with a 3-of-5 quorum.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">From an application developer’s perspective, this may look like a relatively smooth infrastructure migration. \u003Cstrong>At MoveBit, we think the more interesting security question is not whether the new Pyth Core remains API-compatible, but whether the protocol consuming it still operates under the same trust assumptions.\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">From a security perspective, however, it exposes a much deeper issue:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-indent-start-3 docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14 docx-color-56687a\" style=\"color: rgb(86, 104, 122)\">\u003Cstrong>Stable ABI does not imply a stable trust boundary.\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The interface may remain unchanged. Consumer code may not change at all. Yet the answer to a much more important question—\u003Cem>why should this price be trusted?\u003C\u002Fem>—has changed.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">For Sui protocols that depend on external oracles, the security boundary therefore cannot stop at \u003Cstrong>get_price()\u003C\u002Fstrong>, freshness checks, or confidence intervals. It also has to include oracle versions, verification paths, package identity, and dependency lifecycle.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">We can describe this class of dependency as \u003Cstrong>Oracle Version Coupling\u003C\u002Fstrong>.\u003C\u002Fspan>\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-22\">\u003Cstrong>1. Same ABI, Different Trust Root\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Dependency reviews often treat compatibility and security compatibility as roughly the same thing.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">If an upgrade preserves function signatures, keeps the ABI compatible, leaves price feed IDs unchanged, and requires no modification to consumer logic, engineers may reasonably conclude that migration risk is limited.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">But the Pyth Core upgrade shows why that assumption is incomplete.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The previous trust path can be simplified as:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Pythnet \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Wormhole Guardians 13 \u002F 19 signatures \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong> Pyth Core \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong> Consumer\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The new architecture instead looks more like:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>5 Independent Routers \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>3 \u002F 5 quorum \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Pyth Core \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Consumer\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">From the consumer’s point of view, the same price feed may still arrive through an almost identical interface. Yet the security assumptions behind that price have changed.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">So an oracle upgrade review should not stop at:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 6pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>ABI Diff \u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 6pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>API Diff \u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Storage Diff\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">It should also include:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Trust-Root Diff\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Security reviewers should ask: Who now produces the data? Who can attest to it? What quorum is sufficient? What exactly does the verifier prove? Which failure assumptions changed between versions?\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">API compatibility tells us \u003Cstrong>whether the system can still be called\u003C\u002Fstrong>. Trust-root compatibility tells us \u003Cstrong>whether we can still trust the result for the same reasons\u003C\u002Fstrong>.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Those are fundamentally different questions.\u003C\u002Fspan>\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-22\">\u003Cstrong>2. On Sui, Package Identity Becomes Part of Security State\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The Pyth migration is particularly interesting on Sui because consumers reference concrete package identities rather than an abstract upgradeable endpoint that can always be switched transparently on their behalf.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">A simplified dependency chain looks like this:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Hermes \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Price Payload \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Pyth Package \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Pyth State \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Consumer\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Under stable conditions:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Old Hermes × Old Verifier ✓ \u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>New Hermes × New Verifier ✓\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">But during migration, a combination such as:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>New Hermes × Old Verifier ✕\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">may fail.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Nothing has necessarily been compromised. There is no forged price, no signature bypass, and no corrupted state.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Instead, the system enters a more subtle failure mode:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-indent-start-3 docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14 docx-color-56687a\" style=\"color: rgb(86, 104, 122)\">\u003Cstrong>Version-valid components can still form an invalid system state.\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">This is why a package ID should not be treated as mere deployment metadata when critical financial operations depend on it.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">If \u003Cstrong>borrow\u003C\u002Fstrong>, \u003Cstrong>liquidate\u003C\u002Fstrong>, \u003Cstrong>redeem\u003C\u002Fstrong>, or \u003Cstrong>settle\u003C\u002Fstrong> depends on a specific external package, then the identity and lifecycle of that package have effectively become part of the protocol’s runtime security state.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">That is the practical significance of Oracle Version Coupling.\u003C\u002Fspan>\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-22\">\u003Cstrong>3. A Dependency Does Not Need Your UpgradeCap to Affect Your Critical Path\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Traditional access-control reviews focus on capabilities such as:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>UpgradeCap AdminCap PauseCap TreasuryCap\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The goal is to answer a familiar question:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-indent-start-3 docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14 docx-color-56687a\" style=\"color: rgb(86, 104, 122)\">\u003Cstrong>Who can change the protocol?\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">But external dependencies create another control plane that may not appear anywhere in the protocol’s own authority graph.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Consider a lending protocol that directly binds liquidation logic to a particular Pyth package:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cimg alt=\"IMG_256\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F2f7df4a4faf35d1685e10dd6e159eb2f.jpg\" style=\"width: 414.6pt\">\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Pyth does not hold the lending protocol’s \u003Cstrong>UpgradeCap\u003C\u002Fstrong>. It cannot modify the lending code\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Yet if the Pyth package lifecycle changes in a way that makes this historical call path unusable, liquidation may still stop working.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">This leads to a more useful security observation:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-indent-start-3 docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14 docx-color-56687a\" style=\"color: rgb(86, 104, 122)\">\u003Cstrong>A dependency does not need your UpgradeCap to change the reachability of your critical state transitions.\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The right concept here is not “external upgrade authority” in the strict capability sense. It is \u003Cstrong>Dependency-Controlled Availability\u003C\u002Fstrong>.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">And that dependency can expand the protocol’s real:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Effective Upgrade Surface\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The protocol’s visible authority graph may look like:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Protocol Admin \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Protocol Upgrade\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">But the operational reality may be closer to:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cimg alt=\"IMG_257\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002Fc9a2684736ccd72b73488d7359ba9d9e.jpg\" style=\"width: 415.2pt\">\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">This is also why hard-coding a specific oracle implementation inside core business logic is fragile.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">A better pattern is to keep verification at the transaction-construction layer—for example, inside a Programmable Transaction Block—using the currently valid verifier, and let the protocol consume the resulting verified state:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cimg alt=\"IMG_258\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F846583b5e5e9efc23e2e81f56860bcd5.jpg\" style=\"width: 414.8pt\">\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The protocol should ideally depend on the semantic statement:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>“This price has been validly verified.”\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">rather than:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>“This price must be verified by Verifier V1.”\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">A useful design principle here is:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-indent-start-3 docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14 docx-color-56687a\" style=\"color: rgb(86, 104, 122)\">\u003Cstrong>Pin semantics, not implementations.\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">This does not eliminate dependency risk, but it prevents implementation identity from being unnecessarily embedded into core financial logic.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">This is why MoveBit’s review of oracle-dependent Sui protocols goes beyond price correctness and contract-level integration. The dependency graph itself—package identity, verification assumptions, migration states, and critical-path availability—needs to be treated as part of the protocol’s attack surface.\u003C\u002Fspan>\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-22\">\u003Cstrong>4. Oracle Upgrades Should Be Audited as Distributed State Transitions\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Once we accept this model, an oracle upgrade can no longer be reviewed as a simple transition from one package to another:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Old Package \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>New Package\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The real dependency graph is broader:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Data Infrastructure \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Hermes \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Signed Payload \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Verification Package  \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→  \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>State Object \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-font-arial docx-size-14\">\u003Cstrong>→ \u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan class=\"docx-size-14\">\u003Cstrong>Consumer Protocol\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">This exposes another important distinction:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-indent-start-3 docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14 docx-color-56687a\" style=\"color: rgb(86, 104, 122)\">\u003Cstrong>Blockchain atomicity ends at the transaction boundary; oracle atomicity extends across the dependency graph.\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">A PTB can execute atomically. But an oracle migration may also involve backend deployment, SDK upgrades, endpoint switching, package migration, state-object updates, and consumer configuration. Those operations do not automatically share the same atomic boundary.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">That means the most important security target is often not the state before or after the upgrade, but the states in between.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">A focused review should cover three areas.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Trust-Root Diff:\u003C\u002Fstrong> Did the signer set, quorum, verification assumptions, or failure model change?\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Dependency-Identity Diff:\u003C\u002Fstrong> Does critical business logic directly depend on a package identity that can become obsolete?\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Migration-State Testing:\u003C\u002Fstrong> What happens under mismatched combinations such as \u003Cstrong>New Data × Old Verifier \u003C\u002Fstrong>or \u003Cstrong>Old Data × New Verifier\u003C\u002Fstrong>? Does the protocol fail closed, fail open, continue consuming stale data, or recover safely?\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">For lending and perpetual protocols, this matters especially because a version mismatch may begin as an availability problem but later become an economic one if stale prices remain usable or liquidations stop executing.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The security target should therefore be:\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Before Upgrade ✓ \u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>During Upgrade ✓ \u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>After Upgrade ✓\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">—not merely proving that the two stable endpoints work.\u003C\u002Fspan>\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-22\">\u003Cstrong>5. Practical Recommendations\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">For Sui protocols that depend on upgradeable oracles, a few implementation principles can materially reduce version coupling.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">First, \u003Cstrong>separate verification from consumption\u003C\u002Fstrong>. Keep the specific verifier implementation outside core financial logic where possible, and let the protocol consume verified price state rather than a hard-coded package call.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Second, \u003Cstrong>design a degraded mode for oracle failures\u003C\u002Fstrong>. If verification becomes unavailable, the protocol should generally block risk-increasing actions such as new borrowing or leverage while still allowing risk-reducing actions such as repayment or adding collateral.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">Third, \u003Cstrong>test migration intermediates explicitly\u003C\u002Fstrong>. Do not validate only the pre-upgrade and post-upgrade configurations. Intentionally test mismatched data\u002Fverifier combinations and make sure the system fails safely and has a clear recovery path.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The goal is not to prevent dependencies from ever changing. It is to ensure that dependency evolution does not silently rewrite the protocol’s security boundary.\u003C\u002Fspan>\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-22\">\u003Cstrong>Conclusion\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">At MoveBit, we believe oracle security should be reviewed as part of the protocol’s full dependency lifecycle—not only at deployment, but through upgrades, migrations, and failure states.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">The question is no longer just whether a price is correct. It is whether the protocol can continue to verify and consume that price safely as the infrastructure around it evolves.\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-size-14\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-14\">\u003Cstrong>Stable interfaces are useful. Stable security assumptions matter more.\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002Fb6aad19bf61579649903f2fc14221cbf.png","2026-08-26T06:45:48Z","2026-08-26T14:45:48Z","7 min read","Stable ABI, Changing Trust Root: How the Pyth Core Upgrade Redefines Sui Oracle Security cover image",{"slug":49,"category":7,"categoryLabel":6,"subcategoryLabel":17,"authorName":30,"title":50,"excerpt":51,"contentHtml":52,"coverUrl":53,"publishedAt":54,"updatedAt":55,"readTime":56,"cover":53,"hasCover":26,"coverAlt":57},"can-aptos-move-really-avoid-reentrancy-what-function-values-changed-13195c","Can Aptos Move Really Avoid Reentrancy? What Function Values Changed","For a long time, many Move developers have operated under a simple assumption: reentrancy is primarily a Solidity problem, and Move largely avoids it by design.","\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">For a long time, many Move developers have operated under a simple assumption: \u003Cstrong>reentrancy is primarily a Solidity problem, and Move largely avoids it by design.\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">That assumption was broadly accurate for earlier versions of Move. Static module dependencies, strict resource semantics, and VM-level protections made the classic Solidity attack pattern difficult to reproduce: an external call re-enters a function before its previous execution has finished, allowing the same state to be manipulated repeatedly.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">With the introduction of \u003Cstrong>Function Values in Aptos Move 2.2\u003C\u002Fstrong>, however, that security model became more nuanced.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Function Values allow functions to be passed around and invoked dynamically. This makes a call path like the following possible:\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Module A → Module B → Function Value callback → Module A\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Module A can pass a callback to Module B, and B can execute that callback before A&#39;s original execution has completed. In other words, execution can re-enter Module A while the first invocation is still active.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">At first glance, this looks very similar to traditional reentrancy. But there is an important difference.\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">\u003Cspan class=\"docx-size-22\">Move Still Has Resource Locking\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">When a module is re-entered through a Function Value, the Move VM restricts access to resources defined by that module.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">For example, if Module A is already active and the callback re-enters A, another attempt to access A&#39;s own resource may look like this:\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-bottom: 24.5pt\">borrow_global&lt;Balance&gt;(addr);\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-bottom: 24.5pt\">move_from&lt;Balance&gt;(addr);\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">If Balance is defined by the re-entered module, the VM&#39;s resource-locking rules can prevent the second access and abort the transaction.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">This means Function Values do \u003Cstrong>not\u003C\u002Fstrong> simply reintroduce the classic Solidity pattern where an attacker repeatedly withdraws funds before a balance is updated.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">The more interesting security boundary appears one layer deeper.\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">\u003Cspan class=\"docx-size-22\">Resource Locking Does Not Protect Every Piece of State\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Resource locking protects resources belonging to the module being re-entered. It does not automatically freeze every external state dependency involved in the transaction.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Consider a function in Module A with the following execution flow:\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Check external state → Execute user-controlled callback → Continue using the earlier check\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Now assume that the callback can modify a resource managed by another module, or otherwise change external state that Module A relies on.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">A simplified flow might look like this:\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-bottom: 24.5pt\">1. Module A checks that the user&#39;s limit is 100.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-bottom: 24.5pt\">2. Module A executes an external Function Value.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-bottom: 24.5pt\">3. The callback modifies state related to that limit.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-bottom: 24.5pt\">4. Execution returns to Module A.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-bottom: 24.5pt\">5. Module A continues using the result from step 1.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">The problem is no longer simply “the same balance was withdrawn twice.”\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Instead, the issue becomes a combination of \u003Cstrong>reentrancy, cross-module state manipulation, and TOCTOU — Time of Check to Time of Use\u003C\u002Fstrong>.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Module A made a security decision based on one version of the state, but by the time that decision is acted upon, the underlying state may have changed.\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">\u003Cspan class=\"docx-size-22\">Function Values Expand the Trust Boundary\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">This becomes particularly important when a contract accepts arbitrary Function Values, callbacks, or hooks supplied by external callers.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">In those cases, an audit should not stop at asking:\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">\u003Cstrong>Can this module&#39;s own resources be accessed twice?\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">It should also ask:\u003C\u002Fp>\u003Cul>\u003Cli>What external state can change while the callback is executing?\u003C\u002Fli>\u003Cli>Do permission, balance, price, or quota checks performed before the callback remain valid afterward?\u003C\u002Fli>\u003Cli>Is the Function Value controlled by the caller?\u003C\u002Fli>\u003Cli>Which modules can that callback invoke?\u003C\u002Fli>\u003Cli>Which resources can those modules modify?\u003C\u002Fli>\u003Cli>Does the original function rely on any state that should be revalidated after control returns?\u003C\u002Fli>\u003C\u002Ful>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Where security-sensitive logic depends on mutable external state, critical conditions may need to be checked again at the point of use rather than assuming that a pre-callback validation remains valid.\u003C\u002Fp>\u003Ch3 class=\"docx-heading docx-size-22\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">\u003Cspan class=\"docx-size-22\">The Security Model Has Changed, Not Disappeared\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">The right conclusion is not:\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">\u003Cstrong>“Move now has the same reentrancy problem as Solidity.”\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">That would be misleading.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Move&#39;s VM and resource model still prevent many forms of classic reentrancy. What Function Values change is the boundary of what developers and auditors need to reason about.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">Once \u003Cstrong>Function Values, external resources, and pre-callback state checks\u003C\u002Fstrong> appear in the same execution path, reentrancy-related state changes and TOCTOU conditions become part of the threat model.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">For Move developers, the key question is no longer only whether a module can be re-entered.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">It is also:\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">\u003Cstrong>What can change while control is outside the module, and are the assumptions made before that external execution still valid when control returns?\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">That is the security boundary Function Values have introduced into modern Aptos Move.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">At \u003Cstrong>MoveBit\u003C\u002Fstrong>, we review not only isolated functions, but also the state transitions and trust boundaries created by callbacks, Function Values, and cross-module interactions.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">If you&#39;re building on Aptos or other Move-based ecosystems, these are exactly the kinds of edge cases that deserve attention before deployment.\u003C\u002Fp>\u003Cp style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24.5pt\">— \u003Cstrong>MoveBit Research\u003C\u002Fstrong>\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F2e24434a92f775515edf49221e289d0c.jpg","2026-08-18T03:18:54Z","2026-08-18T11:24:25Z","4 min read","Can Aptos Move Really Avoid Reentrancy? What Function Values Changed cover image",{"slug":59,"category":7,"categoryLabel":6,"subcategoryLabel":60,"authorName":30,"title":61,"excerpt":62,"contentHtml":63,"coverUrl":64,"publishedAt":65,"updatedAt":66,"readTime":67,"cover":64,"hasCover":26,"coverAlt":68},"when-account-history-was-misclassified-as-deposit-proof-a-technical-analysis-of-the-xrpl-coreum-bridge-vulnerability-f867e8","Incident Analysis","When Account History Was Misclassified as Deposit Proof: A Technical Analysis of the XRPL–Coreum Bridge Vulnerability","The issue in the XRPL–Coreum bridge incident appears straightforward: when identifying inbound XRPL transfers, the relayer failed to verify whether the Payment Destination was the bridge address.","\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The issue in the XRPL–Coreum bridge incident appears straightforward: when identifying inbound XRPL transfers, the relayer failed to verify whether the Payment Destination was the bridge address.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">However, treating the incident as nothing more than a missing if statement would miss the more important issue. The relayer used an incomplete set of conditions to determine whether an XRPL transaction represented a valid bridge deposit. As a result, a transaction associated with the bridge account could be incorrectly classified as an inbound deposit and then converted into evidence accepted on the Coreum side.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The vulnerability therefore involved more than a single field check. It affected transaction discovery, inbound transfer classification, memo parsing, evidence generation, and the multi-relayer verification process.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">From MoveBit’s security research perspective, this is also a useful case for examining a broader class of cross-chain risks. A contract on the destination chain may be secure, while the off-chain component responsible for interpreting source-chain transactions introduces incorrect state. For Move-based bridges, this boundary deserves the same level of review as the on-chain contract itself.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">1. account_tx Can Discover Transactions, but It Cannot Prove a Deposit\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The Coreum relayer monitors the bridge account using XRPL’s account_tx RPC method. This is a reasonable approach because account_tx returns validated transactions associated with a specified account and can therefore be used to identify candidate transactions for further processing.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The problem is that a transaction being associated with an account does not mean that the transaction transferred assets to that account.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The results returned by account_tx should therefore be treated only as candidate transactions. Before classifying any of them as an XRPL-to-Coreum deposit, the relayer still needs to verify the Payment direction, destination, asset, amount, memo, and other relevant fields.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The processing logic can be simplified as follows:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-bottom: 24pt\">\u003Cimg alt=\"1111111\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002Fa255d020e432cb797f063461a93e72a7.jpg\" style=\"width: 264.2pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-bottom: 24pt\">The problem is that the code effectively sends any transaction not initiated by the bridge into the incoming-transaction processing path.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">A transaction not being sent by the bridge does not mean that it was sent to the bridge. A correct inbound Payment check must at least confirm:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">require(payment.Destination == bridgeAddress)\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-bottom: 24pt\">Without this check, a transaction that involves the bridge account but does not actually transfer funds to it may still be processed as a deposit.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">2. The Relayer Validated the Transaction State but Not the Full Deposit Conditions\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The incoming-transaction path did perform several validations. The public implementation can be simplified to something like:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"222222\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F74001cf6561c302ac19ff3aef0b1000f.jpg\" style=\"width: 298.3pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">These checks confirm that the XRPL transaction was validated, that the Payment succeeded, that the transaction type was correct, that a Coreum recipient could be extracted from the memo, and that the delivered amount could be obtained from the transaction metadata.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">However, these conditions are still not enough to prove that the bridge received the funds.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">DeliveredAmount is particularly important here. It represents the amount actually delivered by a Payment to its recipient, but it does not independently prove that the recipient was the bridge. Even if tx.success == true and DeliveredAmount is present, the transaction cannot automatically be treated as a bridge deposit.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The validation logic must also enforce:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"3333333\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002Fd9fa1cace233519377d2ddbc2a13b2c6.jpg\" style=\"width: 271.2pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The underlying transaction may therefore be completely valid on XRPL while still failing to satisfy the bridge’s own deposit requirements.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">3. Memo Data Should Be Used for Routing, Not as Proof of Deposit\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The XRPL–Coreum bridge uses memos to carry cross-chain routing information, such as the destination Coreum address. The relayer parses this memo to determine where the bridged assets should eventually be credited on Coreum.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">This design is common, but memo data is controlled by the transaction sender. It can provide routing information, but it should not be used as evidence that a valid bridge deposit occurred.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">An attacker can construct a valid XRPL Payment containing a correctly formatted bridge memo. A valid memo only proves that the transaction contains data matching the bridge’s expected format. It does not prove that the Payment Destination is the bridge.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">A safer processing order is:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"444444\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F0fe82016b32180024c3cc691a55673a0.jpg\" style=\"width: 166.2pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The system should first confirm that the transaction actually transferred assets to the bridge, then verify the asset and amount, and only after that use the memo to determine the cross-chain recipient.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">If the destination has not yet been verified, attacker-controlled memo data should not be allowed to influence evidence generation.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">4. Missing Destination Data in the Evidence Limited Coreum-Side Verification\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Another important issue is the loss of transaction context when XRPL data is converted into evidence for Coreum.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The public XRPLToCoreumTransferEvidence structure is roughly:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"5555555\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002Ff71eca57bad8594ccb831c9a5eecc809.jpg\" style=\"width: 252.9pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The XRPL Payment Destination is not included.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">This means that the relayer has access to the full XRPL transaction during processing, but after the evidence object is created, the Coreum side receives only a subset of those fields.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The original transaction contains information such as the sender, destination, asset, amount, transaction result, and memo. The evidence retains only part of that context.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">As a result, if the relayer fails to validate the destination before creating the evidence, the Coreum contract may not have enough information to independently confirm that the Payment was actually sent to the bridge.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">This design pattern requires careful handling. Any field that directly determines whether cross-chain assets can be credited or released should be fully validated before evidence is created. Where appropriate, fields such as Destination can also be included in the evidence so that the on-chain logic can perform an additional check.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">5. Multiple Relayers Do Not Protect Against Shared Validation Bugs\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The Coreum bridge uses an evidence-threshold mechanism. Multiple trusted relayers must submit matching evidence before the bridge proceeds with the cross-chain workflow.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">This mechanism can reduce the risk of a single relayer acting maliciously, being compromised, or malfunctioning. However, it does not automatically protect against a validation bug shared by every relayer.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">If multiple relayers run the same software version and that implementation is missing the Destination == bridgeAddress check, each relayer may classify the same invalid transaction in the same way and submit matching evidence.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The process can look like this:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"666666\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F1c1501d8a74a280b3566691893b1627e.jpg\" style=\"width: 204.1pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">An N-of-M relayer model shows that multiple relayers reached the same conclusion about a transaction. It does not prove that the classification rule used by those relayers is correct.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Relayer count and relayer validation logic are therefore separate security concerns. Increasing the number of relayers reduces certain single-point-of-failure risks, but it does not prevent a shared software defect from reaching the evidence threshold.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">6. Multisig Protects Signing Authority, but It Cannot Correct Invalid Bridge State\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Assets on the XRPL side of the bridge are protected by a multisignature account. Multisig reduces the risk that a single private key or signer can directly control bridge funds.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">However, the vulnerability occurred earlier in the workflow, during state validation.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">If invalid deposit evidence has already been accepted on Coreum and the system generates a withdrawal request based on that state, the withdrawal may appear completely valid to the signers.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">In that situation, the final XRP transaction can be generated through the normal workflow and signed by the required number of authorized signers. The multisig mechanism has not been bypassed, and the signature process itself is functioning correctly.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The problem is that the withdrawal was created from incorrect cross-chain state.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Multisig can prevent unauthorized transfers, but it cannot determine whether the deposit evidence that produced a withdrawal request was valid. Custody security and cross-chain state verification therefore need separate controls. Multisig cannot replace upstream transaction validation.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">7. Incoming Payment Verification Should Bind All Deposit-Critical Fields\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">A safer implementation should fully validate whether an Incoming Payment satisfies the definition of a bridge deposit before generating evidence.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">For example:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"777777\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F0e207cd3c56c625332bff6f14cd96b27.jpg\" style=\"width: 295pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The destination check is only one part of the solution. Sender, destination, asset, amount, recipient, and transaction hash should all be included in the validation logic.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Only after all of these conditions are satisfied should the transaction be classified as a valid XRPL-to-Coreum deposit and used to generate cross-chain evidence.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">8. Tests Should Cover Transactions That Are Valid on XRPL but Invalid for the Bridge\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Bridge relayer tests should not focus only on normal deposits and obviously malformed transactions. They should also cover transactions that are fully valid under XRPL rules but do not satisfy the bridge’s business logic.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Examples include:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"8888888\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F7364f4b31a61bba11702114a4fcbdec3.jpg\" style=\"width: 300.4pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">All of these transactions may pass XRPL consensus and execute successfully. Their validity at the protocol level therefore cannot be used as proof that they represent valid bridge deposits.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The relayer must apply bridge-specific semantic validation on top of the source chain’s transaction rules.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">9. Runtime Monitoring Can Provide a Second Layer of Protection\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">In addition to fixing the transaction-validation logic, a bridge should monitor reserves and cross-chain accounting for abnormal behavior.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The Coreum bridge already includes a kill switch. This mechanism can be combined with asset-flow and accounting checks so that unusual conditions trigger an alert or halt.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">For example:\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cimg alt=\"999999\" src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002Ff76fd144e8f3bac3eb47ce7b74c1df33.jpg\" style=\"width: 253.2pt\">\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">These controls do not replace relayer validation, but they can provide additional protection if a bug in the verification logic allows invalid state to enter the system.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">This is especially important for bridges because they combine several independent components, including source-chain parsing, off-chain relayers, threshold verification, smart contracts, key management, and asset accounting. A failure in one component should not automatically result in unrestricted asset outflow.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">Implications for Move Developers\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The same issue is particularly relevant to cross-chain systems built in the Move ecosystem. In MoveBit’s security work across Move-based networks, bridge security cannot be evaluated only from the Move contract layer. The relayer and source-chain verification logic are also part of the system that determines whether assets can be minted, credited, or released.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Move’s type system, resource model, ownership rules, and bytecode verification can prevent many classes of on-chain asset-handling errors. However, these mechanisms can only ensure that Move code executes safely according to the state and inputs it receives. They cannot determine whether information supplied by an off-chain system or another blockchain is correct.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">If an off-chain relayer submits invalid deposit evidence to a Move contract and the contract has no independent way to verify the corresponding source-chain transaction, the contract may still mint assets, update balances, or allow withdrawals based on incorrect evidence, even if the Move code itself has no type-safety or resource-management flaws.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">For Move bridges and other cross-chain infrastructure, this is why MoveBit’s security reviews look beyond the Move contracts themselves. Relayer behavior, source-chain transaction parsing, evidence construction, replay protection, and the handling of security-critical fields all need to be reviewed when they can directly affect on-chain asset state.\u003C\u002Fp>\u003Cp class=\"docx-align-justify docx-size-18\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">\u003Cspan class=\"docx-size-18\">Security Takeaway\u003C\u002Fspan>\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">The immediate issue in the XRPL–Coreum bridge incident was the absence of a Destination == bridgeAddress check in the Incoming Payment flow. At the system level, however, the more important problem was that the relayer used incomplete conditions to determine whether an XRPL transaction represented a valid bridge deposit.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">A source-chain transaction executing successfully only proves that it satisfies the source chain’s protocol rules. It does not prove that it satisfies the bridge’s deposit requirements. The relayer must independently validate the destination, asset, amount, transaction result, memo, transaction hash, and any other fields that directly affect bridge accounting before generating evidence for the destination chain.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">Multi-relayer thresholds, multisig custody, and Move’s on-chain safety mechanisms address different categories of risk. None of them can replace complete source-chain event validation.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">For cross-chain systems, one of the most important security questions is simple: \u003Cstrong>what exact conditions must be satisfied before a source-chain transaction is classified as a valid bridge deposit?\u003C\u002Fstrong> Those conditions should be explicit, complete, and enforced before the evidence is submitted to the destination chain.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">For MoveBit, this is also an important part of how we approach cross-chain security. Reviewing a Move contract alone is not enough when off-chain relayers, source-chain parsers, and evidence-generation logic can directly change the state that the contract receives. A complete bridge security review needs to cover both the on-chain execution logic and the components responsible for producing cross-chain evidence.\u003C\u002Fp>\u003Cp class=\"docx-align-justify\" style=\"line-height: 1.5; margin-top: 0pt; margin-bottom: 24pt\">MoveBit continues to research security issues across Move-based ecosystems, with a focus on smart contract security, cross-chain infrastructure, and the assumptions that affect asset safety beyond the contract itself.\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2026\u002F08\u002F17300163bfb6286567e0bfa39953ad61.png","2026-08-13T05:40:59Z","2026-08-13T13:40:59Z","10 min read","When Account History Was Misclassified as Deposit Proof: A Technical Analysis of the XRPL–Coreum Bridge Vulnerability cover image",{"slug":70,"category":7,"categoryLabel":6,"subcategoryLabel":17,"authorName":18,"title":71,"excerpt":72,"contentHtml":73,"coverUrl":74,"seoTitle":71,"seoDescription":75,"seoImageUrl":74,"publishedAt":76,"updatedAt":77,"readTime":46,"cover":74,"hasCover":26,"coverAlt":78},"bitslab-deep-dive-nanobot-user-security-practice-guide","BitsLab Deep Dive | Nanobot User Security Practice Guide","When an AI Agent possesses system-level capabilities such as shell execution, file read\u002Fwrite, network requests, and scheduled tasks, it is no longer just a \"chatbot\"—it is an operator with real permissions. This means a single command triggered by prompt injection could delete critical data; a supply chain-poisoned Skill could quietly leak credentials; and an unverified business operation could cause irreversible loss.","\u003Col>\n\u003Cli>Introduction\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>When an AI Agent possesses system-level capabilities such as shell execution, file read\u002Fwrite, network requests, and scheduled tasks, it is no longer just a “chatbot”—it is an operator with real permissions. This means: a single command triggered by prompt injection could delete critical data; a supply chain-poisoned Skill could quietly leak credentials; and an unverified business operation could cause irreversible loss.\u003Cbr>Traditional security solutions usually lean toward two extremes: either relying entirely on the AI’s own “judgment” for self-restraint (which is easily bypassed by meticulously crafted prompts) or piling up rigid rules that lock the Agent down (stripping away the Agent’s core value).\u003C\u002Fp>\n\u003Cp>This guide chooses a third path: dividing security responsibilities based on “who performs the check,” ensuring three distinct roles fulfil their respective duties:\u003C\u002Fp>\n\u003Cp>General Users: Serving as the final line of defence, responsible for key decisions and periodic reviews. We provide best practices to reduce cognitive load.\u003Cbr>The Agent Itself: Consciously adhering to behavioural norms and audit processes during runtime. We provide Skills to inject security knowledge directly into the Agent’s context.\u003Cbr>Deterministic Scripts: Mechanically and faithfully executing checks, immune to prompt injection. We provide Scripts to cover common, known danger patterns.\u003C\u002Fp>\n\u003Cp>No single checker is omnipotent. Scripts cannot understand semantics, Agents can be deceived, and humans experience fatigue. However, by combining all three, we can guarantee the convenience of daily use while simultaneously defending against high-risk operations.\u003C\u002Fp>\n\u003Col start=\"2\">\n\u003Cli>General Users (Precautions)\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Users are the ultimate line of defence and the holders of the highest authority in the security system. The following are security matters that users must personally attend to and execute.\u003C\u002Fp>\n\u003Cp>a) API Key Management: \u003C\u002Fp>\n\u003Cp>Set proper permissions for configuration files to prevent unauthorised access:\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F03\u002F420ceff72b521dc5bc9aa803a70fd621.png\" alt=\"Figure1\" title=\"Figure1\">\u003C\u002Fp>\n\u003Cp>Never commit API keys to code repositories!\u003C\u002Fp>\n\u003Cp>b) Channel Access Control (Critical!)\u003Cbr>You must set a whitelist (allowFrom) for every communication channel; otherwise, anyone will be able to chat with your Agent:\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F03\u002F5f3b8d41207ad04c113c498586d1e381.png\" alt=\"Figure2\" title=\"Figure2\">\u003C\u002Fp>\n\u003Cp>⚠️ In the new version, an empty allowFrom means all access is denied. If you want to open it, you must explicitly write [“*”], but this is not recommended.\u003C\u002Fp>\n\u003Cp>c) Do Not Run as Root\u003Cbr>It is recommended to create a dedicated user to run the Agent to avoid excessive permissions:\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F03\u002F4f251bae7690fd1a0b6b0c7d80bfdef1.png\" alt=\"Figure3\" title=\"Figure3\">\u003C\u002Fp>\n\u003Cp>d) Avoid Using Email Channels Where Possible \u003C\u002Fp>\n\u003Cp>Email protocols are complex and carry relatively high risks. Our BitsLab team has discovered and confirmed a [Critical] level vulnerability related to email. Below is the project team’s response; we still have several issues awaiting their confirmation, so please exercise caution when using email-related functional modules.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2026\u002F03\u002F746713b798b1fdd1140b4e3f849f3b7b.png\" alt=\"Figure4\" title=\"Figure4\">\u003C\u002Fp>\n\u003Cp>e) Recommended Deployment in Docker\u003Cbr>It is recommended to deploy Nanobot in a Docker container to isolate it from your daily operating environment, preventing security risks caused by mixed permissions or environments.\u003C\u002Fp>\n\u003Col start=\"3\">\n\u003Cli>Tool Installation Steps\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The following tools are part of the proprietary toolkit developed by BitsLab. For more details, visit the official repository: \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002FBitsLabSec\u002Fnanobot-security-guide\">https:\u002F\u002Fgithub.com\u002FBitsLabSec\u002Fnanobot-security-guide\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>① Download the nanobot-security-guide project to your nanobot skills directory, or send a command to the Agent to run the official installation script:\u003Cbr>curl -sSL \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fraw.githubusercontent.com\u002FBitsLabSec\u002Fnanobot-security-guide\u002Fmain\u002Finstall.sh\">https:\u002F\u002Fraw.githubusercontent.com\u002FBitsLabSec\u002Fnanobot-security-guide\u002Fmain\u002Finstall.sh\u003C\u002Fa> | bash\u003Cbr>↓\u003Cbr>② Once installation is complete, read the security practice guides within the project (such as README.md and SKILL.md) to understand core security configurations and operational recommendations.\u003Cbr>↓\u003Cbr>③ Send a command to your Agent: “Please read this security guide carefully and evaluate whether it is reliable.”\u003Cbr>↓\u003Cbr>④ Following the document prompts, manually configure allowlist.txt and runtime-baseline.txt in the policy\u002F directory to tighten permissions and establish security baselines.\u003Cbr>↓\u003Cbr>⑤ Use the scripts in the scripts\u002F directory to perform security inspections and testing to ensure environmental safety.\u003C\u002Fp>\n\u003Col start=\"4\">\n\u003Cli>Tool Principles\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>SKILL.md \u003C\u002Fp>\n\u003Cp>Intent auditing based on “Cognitive Awakening” breaks through the blind spots where traditional AI passively receives instructions. It features a built-in, mandatory “Self-Wakeup” Chain of Thought (CoT) mechanism that requires the AI to awaken an independent security-auditor persona in the background before processing any user request. By performing contextual analysis and independent judgment of user intent, it actively identifies and intercepts potential high-risk threats, upgrading the system from “mechanical execution” to an “Intelligent Firewall.” When malicious commands (such as reverse shells, sensitive file theft, or large-scale deletions) are detected, the tool executes a standardised hard-interception protocol (outputting a warning: [Bitslab nanobot-sec skills detected sensitive operation…, Intercepted]).\u003C\u002Fp>\n\u003Cp>Malicious Command Execution Interception (Shell &amp; Cron Protection) \u003C\u002Fp>\n\u003Cp>Acts as a “Zero Trust” gateway when the Agent interacts with OS-level commands. This line of defence directly blocks various destructive operations and dangerous payloads (such as rm -rf malicious deletions, permission tampering, reverse shells, etc.). Simultaneously, the tool provides deep runtime inspection capabilities, actively scanning and cleaning system processes and cron jobs for persistent backdoors and malicious execution signatures, ensuring the absolute safety of the local environment.\u003C\u002Fp>\n\u003Cp>Sensitive Data Theft Prevention (File Access Validation) \u003C\u002Fp>\n\u003Cp>Implements strict physical read\u002Fwrite isolation for core assets. The system presets rigorous file validation rules, strictly forbidding the AI from unauthorised reading and exfiltration of sensitive files containing API keys and core configurations, such as config.json or .env. Furthermore, the security engine performs real-time auditing of file-reading logs (e.g., the invocation sequence of the read_file tool) to completely sever the possibility of credential leakage or data exfiltration at the source.\u003C\u002Fp>\n\u003Cp>MCP Skill Security Auditing \u003C\u002Fp>\n\u003Cp>For the MCP (Model Context Protocol) class, the tool automatically audits contextual interactions and data-processing logic. It detects risks such as sensitive information leakage, unauthorised access, and dangerous command injections, and cross-references them against security baselines and whitelists.\u003C\u002Fp>\n\u003Cp>New Skill Downloads and Automated Security Scanning \u003C\u002Fp>\n\u003Cp>When downloading new skills, the tool uses auditing scripts to perform automated static analysis of the code, compare it against security baselines and whitelists, and detect sensitive information or dangerous commands. This ensures that skills are safe and compliant before they are loaded.\u003C\u002Fp>\n\u003Cp>Anti-Tamper Hash Baseline Verification \u003C\u002Fp>\n\u003Cp>To ensure absolute Zero Trust of underlying system assets, the protection shield continuously establishes and maintains SHA256-encrypted signature baselines for critical configuration files and memory nodes. The nightly inspection engine automatically verifies chronological changes in file hashes, capturing any unauthorised tampering or malicious overwrites within milliseconds. This completely eliminates the risk of local backdoor implantation or “poisoning” at the physical storage layer.\u003C\u002Fp>\n\u003Cp>Automated Disaster Recovery Backup and Snapshot Rotation. \u003C\u002Fp>\n\u003Cp>Given that local Agents possess high-level read\u002Fwrite permissions for the file system, the system includes a top-tier automated disaster recovery mechanism. The protection engine automatically triggers a full sandbox-level archive of active workspaces every night, maintaining a security snapshot mechanism with a 7-day retention policy (auto-rotation). Even in extreme cases of accidental damage or erroneous deletion, the development environment can be rolled back losslessly with one click, maximising the continuity and resilience of local digital assets.\u003C\u002Fp>\n\u003Col start=\"5\">\n\u003Cli>Disclaimer\u003Cbr>This guide is intended solely as a reference for security practices and does not constitute any form of security guarantee.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>No Absolute Security: All measures described in this guide (including deterministic scripts, Agent Skills, and user precautions) are “best-effort” protections and cannot cover all attack vectors. AI Agent security is a rapidly evolving field, and new attack methods may emerge at any time.\u003C\u002Fp>\n\u003Cp>User Responsibility: Users deploying and using Nanobot should independently assess the security risks of their operating environment and adjust the recommendations in this guide according to their specific scenarios. Any losses resulting from incorrect configuration, failure to update promptly, or ignoring security warnings are the sole responsibility of the user.\u003C\u002Fp>\n\u003Cp>Not a Substitute for Professional Security Audits: This guide is not a replacement for professional security audits, penetration testing, or compliance assessments. For scenarios involving sensitive data, financial assets, or critical infrastructure, it is strongly recommended to hire a professional security team for an independent evaluation.\u003C\u002Fp>\n\u003Cp>Third-Party Dependencies: The security of third-party libraries, API services, and platforms that Nanobot relies on (such as Telegram, WhatsApp, and LLM providers) is beyond the scope of this guide. Users should monitor security advisories for relevant dependencies and update them promptly.\u003C\u002Fp>\n\u003Cp>Scope of Non-Liability: The maintainers and contributors of the Nanobot project shall not be held liable for any direct, indirect, incidental, or consequential damages arising from the use of this guide or the Nanobot software.\u003C\u002Fp>\n\u003Cp>Use of this software indicates that you understand and accept the aforementioned risks.\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2026\u002F03\u002F3c4245d7eca88c6e2e913dac30c8d36e.jpg","When an AI Agent possesses system-level capabilities such as shell execution, file read\u002Fwrite, network requests, and scheduled tasks, it is no longer just a \"chatbot\"—it is an operator with real permissions. This means a single command triggered by prompt injection could delete critical data; a supply chain-poisoned Sk","2026-03-11T03:15:00Z","2026-08-11T17:56:38Z","BitsLab Deep Dive | Nanobot User Security Practice Guide cover image",{"slug":80,"category":11,"categoryLabel":10,"subcategoryLabel":81,"authorName":18,"title":82,"excerpt":83,"contentHtml":84,"coverUrl":85,"seoTitle":82,"seoDescription":83,"seoImageUrl":85,"publishedAt":86,"updatedAt":77,"readTime":87,"cover":85,"hasCover":26,"coverAlt":88},"how-to-leverage-movebits-sui-aptos-move-analyser-in-cursor","Products & Services","How to Leverage MoveBit’s Sui\u002FAptos Move Analyzer in Cursor","This article walks you step by step through using sui-move-analyzer and aptos-move-analyzer in the Cursor editor, covering installation, initial configuration, common troubleshooting, and workflow best practices.","\u003Cp>This article walks you step by step through using sui-move-analyzer and aptos-move-analyzer in the Cursor editor, covering installation, initial configuration, common troubleshooting, and workflow best practices.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002F58a3538b980ad9332ff5fb93d6822fb9.png\" alt=\"Figure1\" title=\"Figure1\">\u003C\u002Fp>\n\u003Cp>🔐 Why Use Move Analyzer in Cursor?\u003Cbr> Move Analyzer is a language server and VS Code extension created by the MoveBit team for the Move language ecosystems (Aptos \u002F Sui). It provides IDE-level capabilities such as syntax highlighting, intelligent completion, jump to definition\u002Freferences, hover types, real-time diagnostics, and framework integration.\u003C\u002Fp>\n\u003Cp>When combined with Cursor (which supports VS Code extensions + AI assistant), you can enjoy both the “hardcore” language features of Analyzer and Cursor’s AI completion, refactoring, and instruction-based editing—greatly accelerating module\u002Fcontract building, debugging, and reviewing.\u003C\u002Fp>\n\u003Cp>📖 Sui\u002FAptos Move Analyzer Latest Versions: Key Points &amp; Value (Overview)\u003Cbr>✅ Aptos: aptos-move-analyzer v1.1.4\u003C\u002Fp>\n\u003Cp>Key Fix: Resolved parsing crashes caused by comments in Chinese\u002FJapanese\u002FKorean, making it more collaboration-friendly for multilingual teams.\u003Cbr>Auto Update: Automatically downloads the precompiled binary for the relevant platform, reducing manual steps.\u003Cbr>Precompiled packages available for macOS \u002F Ubuntu \u002F Windows. Other platforms can compile manually as described in the repo.\u003C\u002Fp>\n\u003Cp>✅ Sui: sui-move-analyzer v1.3.1\u003C\u002Fp>\n\u003Cp>Key Fix: Fixed the issue where diagnostic information did not display in VS Code. Error messages are now more accurate, and debugging is more stable.\u003Cbr>Official Recommendation: Upgrade to v1.3.1 for the best experience.\u003C\u002Fp>\n\u003Cp>For specific releases, binary packages, source compilation guides, and feedback channels, please visit:\u003C\u002Fp>\n\u003Cp>Aptos Move Analyzer (GitHub Releases): \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002Fmovebit\u002Faptos-move-analyzer\u002Freleases\">https:\u002F\u002Fgithub.com\u002Fmovebit\u002Faptos-move-analyzer\u002Freleases\u003C\u002Fa>\u003Cbr>Sui Move Analyzer (GitHub Releases): \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002Fmovebit\u002Fsui-move-analyzer\u002Freleases\">https:\u002F\u002Fgithub.com\u002Fmovebit\u002Fsui-move-analyzer\u002Freleases\u003C\u002Fa>\u003Cbr>Telegram Group: \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Ft.me\u002Fmoveanalyzer\">https:\u002F\u002Ft.me\u002Fmoveanalyzer\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>💡 How to Use Sui\u002FAptos Move Analyzer Efficiently in Cursor: From Installation to Advanced\u003Cbr>⚠️ Note: Although Aptos and Sui both use the Move language, they have subtle differences. Make sure that when working on one ecosystem, the other analyzer plugin is disabled to avoid conflicts and errors.\u003C\u002Fp>\n\u003Cp>✅ Step 1: Open Cursor, click the extension marketplace on the left, search for sui-move-analyzer \u002F aptos-move-analyzer, then click install.\u003C\u002Fp>\n\u003Cp>Note: The Cursor marketplace sorts extensions by install count, so sui-move-analyzer and aptos-move-analyzer may be further down the list—you may need to scroll.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002F7d159baccdcbc4f3c6edd1fab5af3d6b.png\" alt=\"Figure2\" title=\"Figure2\">\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002F60943f7b9d6c81397dafcde77222d886.png\" alt=\"Figure3\" title=\"Figure3\">\u003C\u002Fp>\n\u003Cp>✅ Step 2: Open any Move project and enable sui-move-analyzer \u002F aptos-move-analyzer.\u003C\u002Fp>\n\u003Cp> Note: sui-move-analyzer and aptos-move-analyzer do not automatically fetch third-party libraries defined in Move.toml. Before use, run sui move build or aptos move compile to pull dependencies, then restart Cursor.\u003C\u002Fp>\n\u003Cp> \u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002Ff0fff1c45f42386e016558271c470bf3.png\" alt=\"Figure4\" title=\"Figure4\">\u003C\u002Fp>\n\u003Cp> ✅ Step 3: Configure language server path (optional). If you want to use a custom language server executable, open the extension settings and specify the path.\u003C\u002Fp>\n\u003Cp>  \u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002F6ad2552ea810d432698da1799020f3af.png\" alt=\"Figure5\" title=\"Figure5\">\u003C\u002Fp>\n\u003Cp>  \u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002F2dc7d82ee6d352061661258bc74bb19b.png\" alt=\"Figure6\" title=\"Figure6\">\u003C\u002Fp>\n\u003Cp>🔧 Troubleshooting\u003Cbr> If sui\u002Faptos-move-analyzer is not available on your platform: Currently supported platforms are windows-msvc \u002F linux-x86-gnu \u002F mac-arm64 \u002F mac-x86. If you are on a different system, you can build the VS Code extension and language server manually.\u003C\u002Fp>\n\u003Cp> ✅ Steps:\u003C\u002Fp>\n\u003Cp> \u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002F2ecf344512fb93b96e97449696efde64.png\" alt=\"Figure \" title=\"Figure7\">\u003C\u002Fp>\n\u003Cp> After building, place \u002Fpath\u002Fto\u002Fxxx-move-analyzer\u002Ftarget\u002Frelease\u002Fsui-move-analyzer in server.path as described in Step 3.\u003C\u002Fp>\n\u003Cp>📖 Conclusion\u003Cbr>By combining sui\u002Faptos-move-analyzer with Cursor, you can stack semantic support for the Move language on top of an AI-driven editing experience, achieving an integrated workflow for development, debugging, and review.\u003C\u002Fp>\n\u003Cp>As long as you follow these three principles—single ecosystem, single plugin; fetch dependencies before launch; manually specify server.path if needed—you will enjoy a stable and smooth experience.\u003C\u002Fp>\n\u003Cp>Wishing you faster and more reliable Move development!\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002F58a3538b980ad9332ff5fb93d6822fb9.png","2025-09-09T03:15:00Z","3 min read","How to Leverage MoveBit’s Sui\u002FAptos Move Analyzer in Cursor cover image",{"slug":90,"category":11,"categoryLabel":10,"subcategoryLabel":81,"authorName":18,"title":91,"excerpt":92,"contentHtml":93,"coverUrl":94,"seoTitle":91,"seoDescription":95,"seoImageUrl":94,"publishedAt":96,"updatedAt":77,"readTime":46,"cover":94,"hasCover":26,"coverAlt":97},"bitslabai-scanner-outperformed-numerous-audit-participants-in-the-competition-securing-second-place","BitsLabAI Scanner outperformed numerous audit participants in the competition, securing second place","BitsLab has developed a cutting-edge AI auditing agent, the BitsLabAI Scanner, designed specifically to analyze and protect Web3 applications. We recently tested this technology in the SuiDex public audit competition, and the results were outstanding. Powered by its AI-driven scanning capabilities, BitsLabAI Scanner outperformed most audit participants, helping our team secure second place.","\u003Cp>BitsLab has developed a cutting-edge AI auditing agent, the BitsLabAI Scanner, designed specifically to analyze and protect Web3 applications. We recently tested this technology in the SuiDex public audit competition, and the results were outstanding. Powered by its AI-driven scanning capabilities, BitsLabAI Scanner outperformed most audit participants, helping our team secure second place.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002Fadb4f2a3cb7023d9299cc41dd02ec050.png\" alt=\"Figure2\" title=\"Figure1\">\u003C\u002Fp>\n\u003Cp>Introduction\u003C\u002Fp>\n\u003Cp>The Web3 landscape is expanding at a breakneck pace, with smart contracts growing ever more complex. While this innovation is exciting, it also introduces significant security risks, especially in emerging ecosystems like Sui. Auditing smart contracts written in Move is a formidable challenge due to the relative scarcity of historical vulnerability data and mature tooling compared to the EVM world.\u003C\u002Fp>\n\u003Cp>To address this critical security gap, Bitslab has developed a cutting-edge AI framework engineered to analyze and secure Web3 applications. We recently put our technology to the test in the public SuiDex Audit Contest, and the results were exceptional. BitsLabAI Scanner played a crucial role in helping our team secure 2nd place, demonstrating its exceptional capability to identify critical security flaws that might otherwise go unnoticed.\u003C\u002Fp>\n\u003Cp>Why We Built BitsLabAI Scanner With a Security-First Approach\u003C\u002Fp>\n\u003Cp>The world of on-chain security is undergoing a radical transformation, driven by advancements in foundational AI. While general-purpose Large Language Models (LLMs) now possess the ability to perform a preliminary analysis of smart contract code, they often lack the specialized, adversarial mindset required for rigorous security auditing. These models are great assistants, but they are not auditors.\u003C\u002Fp>\n\u003Cp>Recognizing this critical gap, we engineered BitsLabAI Scanner with a multi-layered, security-first architecture. It is not a single, monolithic model but an integrated system where specialized AI components work in concert. Each component is purpose-built to solve a specific challenge in smart contract security:\u003C\u002Fp>\n\u003Cp>Semantic Code Analysis: One layer focuses on understanding the intent and logic of the code, moving beyond simple syntax to grasp the business purpose of the contract.\u003C\u002Fp>\n\u003Cp>Vulnerability Detection: Other layers are trained specifically on vast datasets of known exploits and anti-patterns, from reentrancy to complex economic manipulation vectors.\u003C\u002Fp>\n\u003Cp>Exploit Simulation: An advanced component attempts to autonomously generate and validate potential exploit paths, confirming whether a theoretical vulnerability is practically achievable.\u003C\u002Fp>\n\u003Cp>This integrated approach allows our AI to identify intricate logical flaws and subtle attack vectors that both general-purpose AIs and manual audits can easily miss. By combining the speed and scale of AI with the focused precision of a security expert, our framework provides a deeper, more comprehensive analysis, proactively safeguarding the next generation of Web3 applications.\u003C\u002Fp>\n\u003Cp>From Concept to Practice: The True Power of BitsLabAI Scanner\u003C\u002Fp>\n\u003Cp>The capability of BitsLabAI Scanner lies in its departure from traditional static analysis. Instead of simply checking code against a predefined list of bugs, our framework is designed to emulate the cognitive process of an elite security researcher. It analyzes code not just for what it does, but for what it could be forced to do. This involves understanding the economic incentives, potential edge cases, and the adversarial mindset required to uncover truly novel exploits that go beyond common patterns.\u003C\u002Fp>\n\u003Cp>This deep, context-aware approach was the cornerstone of our success in the SuiDex audit. The AI didn’t just provide a list of potential issues; it delivered a prioritized set of actionable insights that guided our expert auditors directly to the most critical flaws. Below, we break down the core capabilities that powered this analysis, each illustrated with a specific finding from the SuiDex protocol.\u003C\u002Fp>\n\u003Cp>Automated Vulnerability Detection: The AI automatically scans smart contracts for common and uncommon vulnerabilities, including reentrancy, integer overflows, access control issues, and precision errors.\u003C\u002Fp>\n\u003Cp>Contextual Understanding: It analyzes the interactions between different parts of the smart contract and external calls to identify logical flaws that might arise from complex dependencies.\u003C\u002Fp>\n\u003Cp>Precision and Accuracy: Our model minimizes false positives while ensuring high accuracy in identifying genuine security risks.\u003Cbr>Scalability: BitsLabAI Scanner can efficiently audit large and complex codebases, making it suitable for a wide range of blockchain projects.\u003Cbr>Facing the Challenge: Key Discoveries That Enabled BitsLabAI Scanner to Outperform Humans in the SuiDex Audit Competition\u003C\u002Fp>\n\u003Cp>Our AI-driven analysis of the SuiDex protocol was incredibly effective, identifying numerous vulnerabilities that could have jeopardized the platform’s integrity and user funds. In total, our process flagged 7 critical and 3 high-severity issues, demonstrating a profound depth of analysis.\u003C\u002Fp>\n\u003Cp>While the complete list remains confidential, we can highlight a few representative findings. These examples demonstrate the AI’s ability to detect a wide range of issues—from deep, architectural flaws in foundational mathematics to subtle yet catastrophic bugs in business logic.\u003C\u002Fp>\n\u003Col>\n\u003Cli>Critical Finding: Incompatible Mathematical Systems in Core Arithmetic (SUIDEXCA-122)\u003Cbr>This was a fundamental architectural flaw discovered by our AI in the protocol’s fixed-point math library.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The Problem: The core arithmetic functions were built on two conflicting mathematical systems. The logic used binary decomposition (splitting numbers by powers of 2) for its calculations, but the protocol’s precision standard was based on a decimal system (a power of 10). Performing binary operations within a decimal-based framework is like mixing meters and feet in the same equation without conversion.\u003C\u002Fp>\n\u003Cp>The Impact: This incompatibility guaranteed that all non-trivial multiplication and division operations would produce unpredictable and incorrect results. It was a ticking time bomb that would have compromised the reliability of the entire AMM, resulting in significant financial discrepancies and a loss of user trust.\u003C\u002Fp>\n\u003Cp>This finding highlights the AI’s capacity to detect complex mathematical flaws, going far beyond surface-level bug checks to question the very mathematical assumptions a protocol is built on.\u003C\u002Fp>\n\u003Col start=\"2\">\n\u003Cli>Critical Finding: Incorrect Swap Logic Flag\u003Cbr>This vulnerability was a classic logic error with severe consequences, pinpointed by the AI’s contextual analysis.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The Problem: A key function responsible for executing a swap from Token A to Token B was calling an internal library to calculate the required input amount. However, it used a hardcoded parameter that incorrectly instructed the library to perform the opposite swap (Token B to Token A).\u003C\u002Fp>\n\u003Cp>The Impact: This seemingly small error would cause the protocol to miscalculate the required input for every trade using this function. This would lead to transactions executing at incorrect and unfair prices or failing altogether, undermining the core functionality of the DEX.\u003C\u002Fp>\n\u003Cp>This showcases the AI’s proficiency in cross-functional contextual analysis. It didn’t just analyze the function in isolation; it traced the entire execution path to identify a critical contradiction in the logic.\u003C\u002Fp>\n\u003Col start=\"3\">\n\u003Cli>High-Severity Finding: Infinite Token Emissions Bug (SUIDEXCA-30)\u003Cbr>This finding demonstrates the AI’s ability to model the long-term economic consequences of a subtle code flaw.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The Problem: A minor error in the time-keeping logic that calculated token rewards failed to properly cap the emissions according to the planned 3-year schedule.\u003C\u002Fp>\n\u003Cp>The Impact: This flaw would have caused the protocol to mint new tokens indefinitely beyond its intended timeline. This would disrupt the project’s entire tokenomic model, leading to hyperinflation and undermining the token’s value, as well as violating the commitments made to its community.\u003Cbr>This demonstrates the AI’s ability to analyze business logic and its long-term economic implications, safeguarding the financial integrity of the protocol.\u003C\u002Fp>\n\u003Cp>Our detailed report was promptly shared with the SuiDex development team, who acknowledged the findings and took immediate action to remediate the issues.\u003Cbr>More Than Second Place: The Value and Significance Behind BitsLabAI Scanner\u003C\u002Fp>\n\u003Cp>BitsLabAI Scanner’s impressive performance in the SuiDex Audit Contest, securing 2nd place and identifying a significant number of critical and high-severity vulnerabilities, serves as a testament to its advanced capabilities. This achievement not only validates the effectiveness of the BitsLabAI Scanner model in smart contract security auditing but also reinforces our commitment to building a more secure, decentralized future. As the blockchain ecosystem continues to expand, the demand for robust and efficient security solutions will only grow, and the BitsLabAI Scanner model is poised to meet this challenge head-on.\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2025\u002F09\u002Fadb4f2a3cb7023d9299cc41dd02ec050.png","BitsLab has developed a cutting-edge AI auditing agent, the BitsLabAI Scanner, designed specifically to analyze and protect Web3 applications. We recently tested this technology in the SuiDex public audit competition, and the results were outstanding. Powered by its AI-driven scanning capabilities, BitsLabAI Scanner ou","2025-09-03T03:15:00Z","BitsLabAI Scanner outperformed numerous audit participants in the competition, securing second place cover image",{"slug":99,"category":11,"categoryLabel":10,"subcategoryLabel":81,"authorName":18,"title":100,"excerpt":101,"contentHtml":102,"coverUrl":103,"seoTitle":100,"seoDescription":101,"seoImageUrl":103,"publishedAt":104,"updatedAt":77,"readTime":87,"cover":103,"hasCover":26,"coverAlt":105},"bitslabs-movebit-releases-latest-versions-of-aptos-and-sui-move-analyzers","BitsLab’s MoveBit Releases Latest Versions of Aptos and Sui Move Analyzers","The MoveBit team, a sub-brand of BitsLab, has simultaneously released aptos-move-analyzer v1.1.4 and sui-move-analyzer v1.3.1, delivering a more stable and efficient local development environment for Move language developers building on the Aptos and Sui blockchains.","\u003Cp>One-stop VSCode plugin update for both Aptos and Sui — critical fixes and a smoother Move development experience\u003C\u002Fp>\n\u003Cp>August 7, 2025 — The MoveBit team, a sub-brand of BitsLab, has simultaneously released aptos-move-analyzer v1.1.4 and sui-move-analyzer v1.3.1, delivering a more stable and efficient local development environment for Move language developers building on the Aptos and Sui blockchains. These updates address critical issues impacting workflows and provide fresh precompiled binaries for multiple platforms, enabling developers to upgrade quickly and start using the latest version right away.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F08\u002Fa41bb0daf14405641cc34ff432a24bbf.png\" alt=\"Figure2\" title=\"Figure1\">\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F08\u002Fea55d5661b0a949b6ec445ce09a568b6.png\" alt=\"Figure2\" title=\"Figure2\">\u003C\u002Fp>\n\u003Ch2 id=\"1-About-the-Move-Analyzer-Series\">1. About the Move Analyzer Series\u003C\u002Fh2>\n\u003Cp>The Move Analyzer suite of VSCode plugins, developed in-house by MoveBit, is designed to offer end-to-end local development support for Move language and its ecosystems (Aptos \u002F Sui). With features like syntax highlighting, intelligent code completion, navigation tools, diagnostics, and framework integration, the plugins empower both beginners and experienced developers to build, debug, and maintain on-chain contracts directly in VSCode.\u003C\u002Fp>\n\u003Cp>Core capabilities include:\u003Cbr>Editing Assistance: Syntax highlighting, auto-completion, outline view, match highlighting, and one-click comments\u003C\u002Fp>\n\u003Cp>Code Navigation: Jump to definition\u002Freferences, hover for type info, inline hints\u003C\u002Fp>\n\u003Cp>Quality Diagnostics: Real-time compiler feedback, lint checks\u003C\u002Fp>\n\u003Cp>Framework Integration: Aptos\u002FSui scaffolding, CLI support, MSL support, and multi-project workspace compatibility\u003C\u002Fp>\n\u003Ch2 id=\"2-Highlights-of-the-Latest-Release\">2. Highlights of the Latest Release\u003C\u002Fh2>\n\u003Ch3 id=\"aptos-move-analyzer-v1-1-4\">aptos-move-analyzer v1.1.4\u003C\u002Fh3>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F08\u002Fbbeeccbfdc3addae668b50eb7aff13de.png\" alt=\"Figure3\" title=\"Figure3\">\u003C\u002Fp>\n\u003Cp>Release Date: August 7, 2025\u003C\u002Fp>\n\u003Cp>Key Fixes: Resolved a crash issue when parsing non-English comments (e.g., Chinese, Japanese, Korean), ensuring compatibility and stability for multilingual codebases.\u003C\u002Fp>\n\u003Cp>Automatic Updates: The plugin now auto-downloads the appropriate precompiled binary for your platform — no manual steps required.\u003C\u002Fp>\n\u003Cp>Precompiled Versions Available:\u003C\u002Fp>\n\u003Cp>aptos-move-analyzer-mac-x86_64-v1.1.4\u003C\u002Fp>\n\u003Cp>aptos-move-analyzer-ubuntu20.04-x86_64-v1.1.4\u003C\u002Fp>\n\u003Cp>aptos-move-analyzer-win-x86_64-v1.1.4.exe\u003C\u002Fp>\n\u003Cp>Manual Build: Developers on other platforms can compile from source via the official GitHub repository.\u003C\u002Fp>\n\u003Cp>Release Link: GitHub Release\u003Cbr>\u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002Fmovebit\u002Faptos-move-analyzer\u002Freleases\u002F\">https:\u002F\u002Fgithub.com\u002Fmovebit\u002Faptos-move-analyzer\u002Freleases\u002F\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>Feedback &amp; Support: Telegram Group\u003Cbr>\u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Ft.me\u002Fmoveanalyzer\">https:\u002F\u002Ft.me\u002Fmoveanalyzer\u003C\u002Fa>\u003C\u002Fp>\n\u003Ch3 id=\"sui-move-analyzer-v1-3-1\">sui-move-analyzer v1.3.1\u003C\u002Fh3>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F08\u002F98f3191379e7ed9a531f973ccdfb518e.png\" alt=\"Figure4\" title=\"Figure4\">\u003C\u002Fp>\n\u003Cp>Release Date: August 7, 2025\u003C\u002Fp>\n\u003Cp>Key Fixes: Resolved an issue where diagnostic messages weren’t displaying correctly in VSCode, improving error prompts and debugging accuracy.\u003C\u002Fp>\n\u003Cp>Upgrade Recommendation: All users are strongly encouraged to update to v1.3.1 for optimal performance.\u003C\u002Fp>\n\u003Cp>Release Link: GitHub Release\u003Cbr>\u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002Fmovebit\u002Fsui-move-analyzer\u002Freleases\u002F\">https:\u002F\u002Fgithub.com\u002Fmovebit\u002Fsui-move-analyzer\u002Freleases\u002F\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>Feedback &amp; Support: Telegram Group\u003Cbr>\u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Ft.me\u002Fmoveanalyzer\">https:\u002F\u002Ft.me\u002Fmoveanalyzer\u003C\u002Fa>\u003C\u002Fp>\n\u003Ch2 id=\"3-Quick-Upgrade-Guide\">3. Quick Upgrade Guide\u003C\u002Fh2>\n\u003Cp>Open VSCode Marketplace, search for and update aptos-move-analyzer or sui-move-analyzer to the latest version.\u003Cbr>Download the matching precompiled binary from the GitHub Release page, extract it, and restart VSCode.\u003Cbr>In plugin settings, configure the executable path under the server path option.\u003C\u002Fp>\n\u003Cp>##4. Looking Ahead\u003C\u002Fp>\n\u003Cp>With the continued growth of the Move language and the Aptos and Sui ecosystems, MoveBit will keep enhancing the stability and feature depth of the Move Analyzer tools. Whether you’re deploying modules on Aptos or writing contracts on Sui, you’ll enjoy a one-stop, high-efficiency, cross-ecosystem development workflow inside VSCode.\u003C\u002Fp>\n\u003Cp>Get started now:\u003Cbr>VSCode Marketplace → Search &amp; Install\u002FUpdate aptos-move-analyzer or sui-move-analyzer\u003C\u002Fp>\n\u003Cp>Documentation &amp; Examples:\u003C\u002Fp>\n\u003Cp>Aptos Version\u003Cbr>\u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002Fmovebit\u002Faptos-move-analyzer\u002Freleases\u002F\">https:\u002F\u002Fgithub.com\u002Fmovebit\u002Faptos-move-analyzer\u002Freleases\u002F\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>Sui Version\u003Cbr>\u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002Fmovebit\u002Fsui-move-analyzer\u002Freleases\u002F\">https:\u002F\u002Fgithub.com\u002Fmovebit\u002Fsui-move-analyzer\u002Freleases\u002F\u003C\u002Fa>\u003C\u002Fp>\n\u003Ch2 id=\"About-MoveBit\">About MoveBit\u003C\u002Fh2>\n\u003Cp>MoveBit, a sub-brand of BitsLab, is a blockchain security company specializing in the Move ecosystem. By pioneering the use of formal verification, MoveBit aims to make the Move ecosystem the most secure in Web3. The team has partnered with top global projects to deliver comprehensive security audits and consists of security veterans from academia and industry, with over a decade of experience and publications in premier security conferences such as NDSS and CCS. As early contributors to the Move ecosystem, they work closely with developers to set the standard for secure Move applications.\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2025\u002F08\u002Fbbeeccbfdc3addae668b50eb7aff13de.png","2025-08-14T03:15:00Z","BitsLab’s MoveBit Releases Latest Versions of Aptos and Sui Move Analyzers cover image",{"slug":107,"category":7,"categoryLabel":6,"subcategoryLabel":17,"authorName":18,"title":108,"excerpt":109,"contentHtml":110,"coverUrl":111,"seoTitle":108,"seoDescription":112,"seoImageUrl":111,"publishedAt":113,"updatedAt":77,"readTime":114,"cover":111,"hasCover":26,"coverAlt":115},"bitslab-research-kasplex-l2-a-light-weight-based-rollup-solution-on-kaspa","BitsLab Research | Kasplex L2 A Light-Weight Based Rollup Solution on Kaspa","As blockchain technology evolves, scalability and programmability remain critical challenges, particularly for blockchains using the UTXO model. Kaspa, a Layer 1 blockchain leveraging a BlockDAG structure, achieves high throughput but lacks native smart contract functionality, a limitation shared by other UTXO-based systems like Bitcoin. To address this, the Kaspa ecosystem has developed Kasplex L2, a Layer 2 solution designed to enable Ethereum Virtual Machine (EVM) compatible smart contracts through a based rollup architecture.","\u003Ch2 id=\"Introduction\">Introduction\u003C\u002Fh2>\n\u003Cp>As blockchain technology evolves, scalability and programmability remain critical challenges, particularly for blockchains using the UTXO model. Kaspa, a Layer 1 blockchain leveraging a BlockDAG structure, achieves high throughput but lacks native smart contract functionality, a limitation shared by other UTXO-based systems like Bitcoin. To address this, the Kaspa ecosystem has developed Kasplex L2, a Layer 2 solution designed to enable Ethereum Virtual Machine (EVM) compatible smart contracts through a based rollup architecture.\u003C\u002Fp>\n\u003Cp>In this article, we provide a technical analysis of Kasplex L2 from the perspective of a security and research firm. Our goal is to evaluate its design, implementation, and implications for UTXO-based blockchains, without advocating for Kaspa or its ecosystem. We’ll explore how Kasplex L2 works, compare it to Bitcoin’s Inscriptions (e.g., BRC-20), and assess its strengths and limitations. This analysis aims to contribute to the broader discourse on scaling solutions for blockchains with constrained programmability.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F05\u002F53cb218effcd84232c837c60e5bbc2af.png\" alt=\"Banner\" title=\"Banner\">\u003C\u002Fp>\n\u003Ch2 id=\"Understanding-Kaspa-Layer-1-A-High-Throughput-UTXO-Blockchain\">Understanding Kaspa Layer 1: A High-Throughput UTXO Blockchain\u003C\u002Fh2>\n\u003Cp>Kaspa is a Layer 1 blockchain that uses a BlockDAG structure, allowing multiple blocks to be produced in parallel. This design, powered by the GHOSTDAG protocol, enables Kaspa to achieve a throughput of 10 BPS performance. Unlike account-based blockchains such as Ethereum, Kaspa employs a UTXO model, where transactions consume unspent outputs and create new ones, ensuring efficient validation.\u003C\u002Fp>\n\u003Cp>While this architecture excels for payment use cases, it poses challenges for programmability. The UTXO model is stateless by nature, lacking the ability to maintain persistent state or execute complex computations—key requirements for smart contracts. As a result, Kaspa’s functionality is limited to simple transfers, prompting the development of Layer 2 solutions to expand its capabilities.\u003C\u002Fp>\n\u003Ch2 id=\"Kasplex-L2-A-Based-Rollup-for-Smart-Contract-Execution\">Kasplex L2: A Based Rollup for Smart Contract Execution\u003C\u002Fh2>\n\u003Cp>The Kaspa ecosystem has explored three L2 approaches: Sparkle, Igra L2, and Kasplex L2. Sparkle remains largely theoretical, and Igra L2 trails in development. Our analysis focuses on Kasplex L2, as it represents the most mature implementation to date.\u003C\u002Fp>\n\u003Cp>Kasplex L2 is a based rollup, a type of Layer 2 scaling solution that relies on the L1 for transaction sequencing and data availability, while offloading computation to the L2. In this design, Kaspa’s L1 determines the canonical order of transactions and ensures their data is publicly accessible, while Kasplex L2 executes EVM bytecode to enable smart contract functionality.\u003C\u002Fp>\n\u003Ch2 id=\"Technical-Design-and-Workflow\">Technical Design and Workflow\u003C\u002Fh2>\n\u003Cp>The core mechanism of Kasplex L2 involves embedding EVM bytecode in the payload of Kaspa L1 transactions. The process can be broken down as follows:\u003C\u002Fp>\n\u003Cp>Transaction Submission: A user submits a transaction to Kaspa L1, including a payload that contains EVM bytecode. For example, the payload might encode a call to a smart contract function like HelloWorld().\u003C\u002Fp>\n\u003Cp>Sequencing by L1: Kaspa’s BlockDAG orders the transaction within its DAG structure, providing a deterministic sequence of all transactions.\u003C\u002Fp>\n\u003Cp>L2 Execution: Kasplex L2 operates as an indexer, scanning the L1 for transactions with payloads. It extracts the EVM bytecode, executes it in the specified order, and updates its state. Invalid or conflicting transactions (e.g., those attempting to double-spend) are discarded.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F05\u002Fb17ab6f1cc2e19dd7f31fe15c54a8fce.png\" alt=\"Figure1\" title=\"Figure1\">\u003C\u002Fp>\n\u003Ch2 id=\"Transaction-Submission-Mechanisms\">Transaction Submission Mechanisms\u003C\u002Fh2>\n\u003Cp>Kasplex L2 supports two methods for submitting transactions, each with distinct implications:\u003C\u002Fp>\n\u003Cp>Canonical Submission: Transactions are submitted directly to Kaspa L1 using a Kaspa-compatible wallet. This approach ensures that no intermediaries are involved, aligning with the decentralization principles of blockchain systems.\u003Cbr>Proxied Submission: Transactions are submitted via a relayer, enabling compatibility with EVM-based tools like MetaMask. The relayer forwards the transaction to Kaspa L1, ensuring it is recorded before the L2 processes it. This method prioritizes user convenience but introduces a dependency on the relayer.\u003C\u002Fp>\n\u003Cp>The proxied submission mechanism enforces atomicity by requiring all L2 transactions to be anchored on the L1. If a transaction originates on the L2 without an L1 record, the relayer submits it to the L1 for confirmation. This design prevents “native” L2 transactions, which could bypass L1 consensus and introduce security risks. Figure 2 illustrates the two submission paths.\u003C\u002Fp>\n\u003Cp>Canonical Path: Wallet → Kaspa L1 → Kasplex L2 .\u003Cbr>Proxied Path: MetaMask → Relayer → Kaspa L1 → Kasplex L2.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fmedia\u002Fmovebit\u002F2025\u002F05\u002Fdd924831a8b9a2cba4f66b2453121c92.png\" alt=\"Figure2\" title=\"Figure2\">\u003C\u002Fp>\n\u003Cp>You may notice the transaction is actually going through the L1 first then interpreted by the L2 indexer. That is exactly how Kasplex L2 works, where the L1 finalises the data, before the L2 reads the transaction then transits the state.\u003C\u002Fp>\n\u003Ch2 id=\"Comparing-Kasplex-L2-with-Bitcoin-Inscriptions\">Comparing Kasplex L2 with Bitcoin Inscriptions\u003C\u002Fh2>\n\u003Cp>To contextualize Kasplex L2, it’s useful to compare it with Bitcoin Inscriptions, specifically BRC-20, a popular mechanism for token issuance on Bitcoin. Both systems aim to extend the functionality of UTXO-based blockchains by leveraging the L1 for data storage and ordering, but they differ in their implementation and goals.\u003C\u002Fp>\n\u003Cp>Similarities\u003C\u002Fp>\n\u003Cp>Data Embedding in L1: Both Kasplex L2 and BRC-20 embed data in L1 transactions. BRC-20 uses Bitcoin’s Tapscript (enabled by the SegWit upgrade) to store token metadata, typically through a three-step process: commit (hash of the data), reveal (the data itself), and spend (token transfer). Kasplex L2 embeds EVM bytecode in the payload of Kaspa L1 transactions, achieving a similar goal of anchoring L2 operations to the L1.\u003C\u002Fp>\n\u003Cp>L1 as the Source of Truth: In both cases, the L1 provides the canonical ordering of operations. BRC-20 relies on Bitcoin’s blockchain to sequence token transfers, while Kasplex L2 uses Kaspa’s BlockDAG to order smart contract executions.\u003C\u002Fp>\n\u003Cp>Indexer Dependency: Both systems depend on off-chain indexers for processing. BRC-20 indexers parse Bitcoin transactions to track token balances, while Kasplex L2’s indexer executes EVM bytecode to maintain smart contract states.\u003C\u002Fp>\n\u003Cp>Differences\u003C\u002Fp>\n\u003Cp>Implementation Efficiency: BRC-20’s three-step process is a workaround for Bitcoin’s rigid protocol, which was not designed to support L2 operations. Kasplex L2 benefits from Kaspa’s more cooperative L1, allowing data to be embedded in a single transaction payload, reducing complexity and overhead.\u003C\u002Fp>\n\u003Cp>Performance Considerations: Bitcoin’s throughput is limited to approximately 7 TPS, with blocks produced every 10 minutes on average, making Inscriptions slow and costly. Kaspa’s 10 BPS upgrade provides a significant performance advantage, enabling Kasplex L2 to handle higher transaction volumes more efficiently.\u003C\u002Fp>\n\u003Cp>Scope and Functionality: BRC-20 is narrowly focused on token issuance and transfers, whereas Kasplex L2 supports full EVM compatibility, allowing for complex smart contracts such as DeFi protocols or NFT marketplaces.\u003C\u002Fp>\n\u003Cp>Protocol Flexibility: Bitcoin’s conservative design prioritizes immutability, requiring L2 solutions to work around its constraints. Kaspa’s L1, while still a UTXO system, is more flexible, enabling tighter integration with L2 solutions like Kasplex.\u003C\u002Fp>\n\u003Cp>This comparison highlights a key insight: while the conceptual approach of using the L1 for data and sequencing is shared, Kasplex L2 leverages Kaspa’s architectural advantages to achieve greater efficiency and broader functionality compared to Bitcoin Inscriptions.\u003C\u002Fp>\n\u003Ch2 id=\"Evaluating-Kasplex-L2-Strengths-and-Limitations\">Evaluating Kasplex L2: Strengths and Limitations\u003C\u002Fh2>\n\u003Cp>From a technical research perspective, Kasplex L2 presents several notable strengths and limitations, which we evaluate below.\u003C\u002Fp>\n\u003Cp>Strengths\u003C\u002Fp>\n\u003Cp>Functional Expansion: Kasplex L2 successfully extends Kaspa’s capabilities by enabling EVM-compatible smart contracts, supporting use cases such as decentralized applications and tokenization that are otherwise infeasible on the L1.\u003C\u002Fp>\n\u003Cp>Efficient Use of L1: By relying on Kaspa’s BlockDAG for sequencing and data availability, Kasplex L2 minimizes the computational burden on the L2, focusing solely on execution. This design aligns well with Kaspa’s high-throughput architecture.\u003C\u002Fp>\n\u003Cp>Public Verifiability: Since all transactions are recorded on the L1, the execution of smart contracts on Kasplex L2 can be independently verified by re-running the EVM bytecode in the canonical order, ensuring transparency.\u003C\u002Fp>\n\u003Cp>Limitations and Risks\u003C\u002Fp>\n\u003Cp>Indexer Trust: The L2’s indexer plays a critical role in executing bytecode and maintaining state. However, there is a risk of indexer misbehavior, such as presenting an incorrect state (e.g., a falsified Merkle root) while maintaining a separate, hidden state. Mitigating this requires a decentralized indexer network, potentially with economic incentives or penalties, which has not yet been implemented.\u003C\u002Fp>\n\u003Cp>Reorganization Challenges: Kaspa’s BlockDAG, while efficient, is susceptible to reorganizations in recent blocks due to its parallel block production. This can force the L2 to revert and re-execute transactions, introducing complexity. \u003C\u002Fp>\n\u003Ch2 id=\"Implications-for-UTXO-Based-Blockchains\">Implications for UTXO-Based Blockchains\u003C\u002Fh2>\n\u003Cp>Kasplex L2 offers a case study in scaling programmability for UTXO-based blockchains, with potential lessons for systems like Bitcoin. Both Kaspa and Bitcoin face similar constraints in supporting smart contracts due to their UTXO models, but Kaspa’s higher throughput and more flexible L1 design provide a more favorable environment for L2 solutions.\u003C\u002Fp>\n\u003Cp>For Bitcoin, Kasplex L2’s design suggests several areas of exploration:\u003C\u002Fp>\n\u003Cp>Relayer Integration: The proxied submission mechanism demonstrates how EVM-compatible tools can be integrated with a UTXO blockchain, a concept that could be adapted for Bitcoin L2 solutions like BitVM.\u003C\u002Fp>\n\u003Cp>Indexer-Based Execution: The use of an indexer to execute off-chain computations while anchoring data on the L1 aligns with Bitcoin’s Inscription model and could inspire new approaches to scaling programmability.\u003C\u002Fp>\n\u003Cp>From a research perspective, Kasplex L2 serves as a valuable experiment, demonstrating how architectural differences between UTXO blockchains (e.g., throughput, protocol flexibility) impact the feasibility of L2 solutions. Its findings can inform the design of scaling solutions across the blockchain ecosystem, particularly for systems prioritizing decentralization and security over native programmability.\u003C\u002Fp>\n\u003Ch2 id=\"Conclusion\">Conclusion\u003C\u002Fh2>\n\u003Cp>Kasplex L2 is a technically sound implementation of a based rollup, enabling EVM-compatible smart contracts on Kaspa by leveraging its L1 for sequencing and data availability. Our analysis highlights its efficiency in utilizing Kaspa’s high-throughput BlockDAG, as well as its ability to extend functionality through EVM compatibility. We view Kasplex L2 as a significant contribution to the study of L2 solutions for UTXO-based blockchains. Its comparison with Bitcoin Inscriptions reveals both shared principles and the impact of L1 design on L2 feasibility. For researchers and developers, Kasplex L2 offers a lens through which to explore the intersection of scalability, programmability, and decentralization in blockchain systems\u003C\u002Fp>\n\u003Ch2 id=\"Reference\">Reference\u003C\u002Fh2>\n\u003Cp>Kasplex Github. [Online]. Available: \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fgithub.com\u002Fkasplex\u002Findexer-executor\">https:\u002F\u002Fgithub.com\u002Fkasplex\u002Findexer-executor\u003C\u002Fa>\u003Cbr>Kaspa Research, “On the Design of Based zk-Rollups over Kaspa’s UTXO-Based DAG Consensus,” 2024. [Online]. Available: \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https:\u002F\u002Fresearch.kas.pa\u002Ft\u002Fon-the-design-of-based-zk-rollups-over-kaspas-utxo-based-dag-consensus\u002F208\">https:\u002F\u002Fresearch.kas.pa\u002Ft\u002Fon-the-design-of-based-zk-rollups-over-kaspas-utxo-based-dag-consensus\u002F208\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>A big shout-out to our researcher @ZorrotChen. Thank you for contributing to this article!\u003C\u002Fp>","\u002Fmedia\u002Fmovebit\u002F2025\u002F05\u002F53cb218effcd84232c837c60e5bbc2af.png","As blockchain technology evolves, scalability and programmability remain critical challenges, particularly for blockchains using the UTXO model. Kaspa, a Layer 1 blockchain leveraging a BlockDAG structure, achieves high throughput but lacks native smart contract functionality, a limitation shared by other UTXO-based sy","2025-05-20T03:15:00Z","9 min read","BitsLab Research | Kasplex L2 A Light-Weight Based Rollup Solution on Kaspa cover image",30,1,10,1792635791889]