[{"data":1,"prerenderedAt":37},["ShallowReactive",2],{"options:asyncdata:2tykd9neomxlh":3},{"blogList":4},[5,19,28],{"slug":6,"category":7,"categoryLabel":8,"subcategoryLabel":9,"authorName":10,"title":11,"excerpt":12,"contentHtml":13,"coverUrl":14,"publishedAt":15,"readTime":16,"cover":14,"hasCover":17,"coverAlt":18},"sui-shared-object-security-how-access-control-flaws-put-defi-protocols-at-risk-9dc56b","research","Research","Industry Research","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","15 min read",true,"Sui Shared Object Security: How Access Control Flaws Put DeFi Protocols at Risk cover image",{"slug":20,"category":7,"categoryLabel":8,"subcategoryLabel":9,"authorName":10,"title":21,"excerpt":22,"contentHtml":23,"coverUrl":24,"publishedAt":25,"readTime":26,"cover":24,"hasCover":17,"coverAlt":27},"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","7 min read","Stable ABI, Changing Trust Root: How the Pyth Core Upgrade Redefines Sui Oracle Security cover image",{"slug":29,"category":7,"categoryLabel":8,"subcategoryLabel":9,"authorName":10,"title":30,"excerpt":31,"contentHtml":32,"coverUrl":33,"publishedAt":34,"readTime":35,"cover":33,"hasCover":17,"coverAlt":36},"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","4 min read","Can Aptos Move Really Avoid Reentrancy? What Function Values Changed cover image",1792060237772]