[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-openzeppelin-upgrade-stylus-contracts":3,"mdc-bbia14-key":36,"related-org-openzeppelin-upgrade-stylus-contracts":1423,"related-repo-openzeppelin-upgrade-stylus-contracts":1552},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":34,"mdContent":35},"upgrade-stylus-contracts","upgrade Stylus smart contracts","Upgrade Stylus smart contracts using OpenZeppelin proxy patterns on Arbitrum. Use when users need to: (1) make Stylus Rust contracts upgradeable with UUPS or Beacon proxies, (2) understand Stylus-specific proxy mechanics (logic_flag, WASM reactivation), (3) integrate UUPSUpgradeable with access control, (4) ensure storage compatibility across upgrades, or (5) test upgrade paths for Stylus contracts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"openzeppelin","OpenZeppelin","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fopenzeppelin.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Web3","web3","tag",{"name":17,"slug":18,"type":15},"Migration","migration",{"name":20,"slug":21,"type":15},"Rust","rust",{"name":23,"slug":24,"type":15},"Smart Contracts","smart-contracts",193,"https:\u002F\u002Fgithub.com\u002FOpenZeppelin\u002Fopenzeppelin-skills","2026-07-13T06:04:28.005287","AGPL-3.0-only",25,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":33},[],"Agent skills for secure smart contract development with OpenZeppelin Contracts libraries","https:\u002F\u002Fgithub.com\u002FOpenZeppelin\u002Fopenzeppelin-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fupgrade-stylus-contracts","---\nname: upgrade-stylus-contracts\ndescription: \"Upgrade Stylus smart contracts using OpenZeppelin proxy patterns on Arbitrum. Use when users need to: (1) make Stylus Rust contracts upgradeable with UUPS or Beacon proxies, (2) understand Stylus-specific proxy mechanics (logic_flag, WASM reactivation), (3) integrate UUPSUpgradeable with access control, (4) ensure storage compatibility across upgrades, or (5) test upgrade paths for Stylus contracts.\"\nlicense: AGPL-3.0-only\nmetadata:\n  author: OpenZeppelin\n---\n\n# Stylus Upgrades\n\n## Contents\n\n- [Stylus Upgrade Model](#stylus-upgrade-model)\n- [Proxy Patterns](#proxy-patterns)\n- [Access Control](#access-control)\n- [Upgrade Safety](#upgrade-safety)\n\n## Stylus Upgrade Model\n\nStylus contracts run on Arbitrum as WebAssembly (WASM) programs alongside the EVM. They share the same state trie, storage model, and account system as Solidity contracts. Because of this, **EVM proxy patterns work identically** for Stylus — a Solidity proxy can delegate to a Stylus implementation and vice versa.\n\n| | Stylus | Solidity |\n|---|---|---|\n| **Proxy mechanism** | Same — `delegatecall` to implementation contract | `delegatecall` to implementation contract |\n| **Storage layout** | `#[storage]` fields map to the same EVM slots as equivalent Solidity structs | Sequential slot allocation per Solidity rules |\n| **EIP standards** | ERC-1967 storage slots, ERC-1822 proxiable UUID | Same |\n| **Context detection** | `logic_flag` boolean in a unique storage slot (no `immutable` support) | `address(this)` stored as `immutable` |\n| **Initialization** | Two-step: constructor sets `logic_flag`, then `set_version()` via proxy | Constructor + initializer via proxy |\n| **Reactivation** | WASM contracts must be reactivated every 365 days or after a Stylus protocol upgrade | Not applicable |\n\nExisting Solidity contracts can upgrade to a Stylus (Rust) implementation via proxy patterns. The `#[storage]` macro lays out fields in the EVM state trie identically to Solidity, so storage slots line up when type definitions match.\n\n## Proxy Patterns\n\nOpenZeppelin Contracts for Stylus provides three proxy patterns:\n\n| Pattern | Key types | Best for |\n|---------|----------|----------|\n| **UUPS** | `UUPSUpgradeable`, `IErc1822Proxiable`, `Erc1967Proxy` | Most projects — upgrade logic in the implementation, lighter proxy |\n| **Beacon** | `BeaconProxy`, `UpgradeableBeacon` | Multiple proxies sharing one implementation — updating the beacon upgrades all proxies atomically |\n| **Basic Proxy** | `Erc1967Proxy`, `Erc1967Utils` | Low-level building block for custom proxy patterns |\n\n### UUPS\n\nThe implementation contract composes `UUPSUpgradeable` in its `#[storage]` struct alongside access control (e.g., `Ownable`). Integration requires:\n\n1. Add `UUPSUpgradeable` (and access control) as fields in the `#[storage]` struct\n2. Call `self.uups.constructor()` and initialize access control in the constructor\n3. Expose `initialize` calling `self.uups.set_version()` — invoked via proxy after deployment\n4. Implement `IUUPSUpgradeable` — `upgrade_to_and_call` guarded by access control, `upgrade_interface_version` delegating to `self.uups`\n5. Implement `IErc1822Proxiable` — `proxiable_uuid` delegating to `self.uups`\n\nThe proxy contract is a thin `Erc1967Proxy` with a constructor that takes the implementation address and initialization data, and a `#[fallback]` handler that delegates all calls.\n\nDeploy the proxy with `set_version` as the initialization call data. Use `cargo stylus deploy` or a deployer contract. The initialization data is the ABI-encoded `setVersion` call:\n\n```rust\nlet data = MyContractAbi::setVersionCall {}.abi_encode();\n\u002F\u002F Pass `data` as the proxy constructor's second argument at deployment time.\n```\n\n### Beacon\n\nMultiple `BeaconProxy` contracts point to a single `UpgradeableBeacon` that stores the current implementation address. Updating the beacon upgrades all proxies in one transaction.\n\n### Context detection (Stylus-specific)\n\nStylus does not support the `immutable` keyword. Instead of storing `__self = address(this)`, `UUPSUpgradeable` uses a `logic_flag` boolean in a unique storage slot:\n\n- The implementation's **constructor** sets `logic_flag = true` in its own storage.\n- When code runs via a proxy (`delegatecall`), the proxy's storage does not contain this flag, so it reads as `false`.\n- `only_proxy()` checks this flag to ensure upgrade functions can only be called through the proxy, not directly on the implementation.\n\n`only_proxy()` also verifies that the ERC-1967 implementation slot is non-zero and that the proxy-stored version matches the implementation's `VERSION_NUMBER`.\n\n> **Examples:** See the `examples\u002F` directory of the [rust-contracts-stylus repository](https:\u002F\u002Fgithub.com\u002FOpenZeppelin\u002Frust-contracts-stylus) for full working integration examples of UUPS, Beacon, and related patterns.\n\n## Access Control\n\nUpgrade functions must be guarded with access control. OpenZeppelin's Stylus contracts do **not** embed access control into the upgrade logic itself — you must add it in `upgrade_to_and_call`:\n\n```rust\nfn upgrade_to_and_call(&mut self, new_implementation: Address, data: Bytes) -> Result\u003C(), Vec\u003Cu8>> {\n    self.ownable.only_owner()?; \u002F\u002F or any access control check\n    self.uups.upgrade_to_and_call(new_implementation, data)?;\n    Ok(())\n}\n```\n\nCommon options:\n- **Ownable** — single owner, simplest pattern\n- **AccessControl \u002F RBAC** — role-based, finer granularity\n- **Multisig or governance** — for production contracts managing significant value\n\n## Upgrade Safety\n\n### Storage compatibility\n\nStylus `#[storage]` fields are laid out in the EVM state trie identically to Solidity. The same storage layout rules apply when upgrading:\n\n- **Never** reorder, remove, or change the type of existing storage fields\n- **Never** insert new fields before existing ones\n- **Only** append new fields at the end of the struct\n- ERC-1967 proxy storage slots are in high, standardized locations — they will not collide with implementation storage\n\nOne difference from Solidity: nested structs in Stylus `#[storage]` (e.g., composing `Erc20`, `Ownable`, `UUPSUpgradeable` as fields) are laid out with each nested struct starting at its own deterministic slot. This is consistent with regular struct nesting in Solidity, but not with Solidity's inheritance-based flat layout where all inherited variables share a single sequential slot range.\n\n### Initialization safety\n\n- The implementation **constructor** sets `logic_flag` and any implementation-only state. It runs once at implementation deployment.\n- `set_version()` must be called via the proxy (during deployment or via `upgrade_to_and_call`) to write the `VERSION_NUMBER` into the proxy's storage.\n- If additional initialization is needed (ownership, token supply), expose a protected initialization function and include `set_version()` in it.\n- Failing to initialize properly can result in orphaned contracts with no owner, uninitialized state, or denied future upgrades.\n\n### UUPS upgrade checks\n\nThe UUPS implementation enforces three safety checks:\n\n1. **Access control** — restrict `upgrade_to_and_call` (e.g., `self.ownable.only_owner()`)\n2. **Proxy context enforcement** — `only_proxy()` reverts if the call is not via `delegatecall`\n3. **Proxiable UUID validation** — `proxiable_uuid()` must return the ERC-1967 implementation slot, confirming UUPS compatibility\n\n### Reactivation\n\nStylus WASM contracts must be **reactivated once per year** (365 days) or after any Stylus protocol upgrade. Reactivation can be done using `cargo-stylus` or the `ArbWasm` precompile. If a contract is not reactivated, it becomes uncallable. This is orthogonal to proxy upgrades but must be factored into maintenance planning.\n\n### Testing upgrade paths\n\nBefore upgrading a production contract:\n\n- [ ] **Deploy V1 implementation and proxy** on a local Arbitrum devnet\n- [ ] **Write state with V1**, upgrade to V2 via `upgrade_to_and_call`, and verify that all existing state reads correctly\n- [ ] **Verify new functionality** works as expected after the upgrade\n- [ ] **Confirm access control** — only authorized callers can invoke `upgrade_to_and_call`\n- [ ] **Check storage layout** — ensure no reordering, removal, or type changes to existing fields\n- [ ] **Verify `VERSION_NUMBER`** is incremented in the new implementation\n- [ ] **Test reactivation** — ensure the upgraded contract can be reactivated\n- [ ] **Manual review** — there is no automated storage layout validation for Stylus Rust contracts; rely on struct comparison and devnet testing\n",{"data":37,"body":39},{"name":4,"description":6,"license":28,"metadata":38},{"author":9},{"type":40,"children":41},"root",[42,51,58,100,105,119,335,347,352,357,487,493,520,634,654,683,713,718,737,743,776,830,847,879,884,903,953,958,990,995,1001,1013,1050,1082,1088,1149,1155,1160,1226,1231,1259,1265,1270,1417],{"type":43,"tag":44,"props":45,"children":47},"element","h1",{"id":46},"stylus-upgrades",[48],{"type":49,"value":50},"text","Stylus Upgrades",{"type":43,"tag":52,"props":53,"children":55},"h2",{"id":54},"contents",[56],{"type":49,"value":57},"Contents",{"type":43,"tag":59,"props":60,"children":61},"ul",{},[62,73,82,91],{"type":43,"tag":63,"props":64,"children":65},"li",{},[66],{"type":43,"tag":67,"props":68,"children":70},"a",{"href":69},"#stylus-upgrade-model",[71],{"type":49,"value":72},"Stylus Upgrade Model",{"type":43,"tag":63,"props":74,"children":75},{},[76],{"type":43,"tag":67,"props":77,"children":79},{"href":78},"#proxy-patterns",[80],{"type":49,"value":81},"Proxy Patterns",{"type":43,"tag":63,"props":83,"children":84},{},[85],{"type":43,"tag":67,"props":86,"children":88},{"href":87},"#access-control",[89],{"type":49,"value":90},"Access Control",{"type":43,"tag":63,"props":92,"children":93},{},[94],{"type":43,"tag":67,"props":95,"children":97},{"href":96},"#upgrade-safety",[98],{"type":49,"value":99},"Upgrade Safety",{"type":43,"tag":52,"props":101,"children":103},{"id":102},"stylus-upgrade-model",[104],{"type":49,"value":72},{"type":43,"tag":106,"props":107,"children":108},"p",{},[109,111,117],{"type":49,"value":110},"Stylus contracts run on Arbitrum as WebAssembly (WASM) programs alongside the EVM. They share the same state trie, storage model, and account system as Solidity contracts. Because of this, ",{"type":43,"tag":112,"props":113,"children":114},"strong",{},[115],{"type":49,"value":116},"EVM proxy patterns work identically",{"type":49,"value":118}," for Stylus — a Solidity proxy can delegate to a Stylus implementation and vice versa.",{"type":43,"tag":120,"props":121,"children":122},"table",{},[123,145],{"type":43,"tag":124,"props":125,"children":126},"thead",{},[127],{"type":43,"tag":128,"props":129,"children":130},"tr",{},[131,135,140],{"type":43,"tag":132,"props":133,"children":134},"th",{},[],{"type":43,"tag":132,"props":136,"children":137},{},[138],{"type":49,"value":139},"Stylus",{"type":43,"tag":132,"props":141,"children":142},{},[143],{"type":49,"value":144},"Solidity",{"type":43,"tag":146,"props":147,"children":148},"tbody",{},[149,184,211,232,278,314],{"type":43,"tag":128,"props":150,"children":151},{},[152,161,175],{"type":43,"tag":153,"props":154,"children":155},"td",{},[156],{"type":43,"tag":112,"props":157,"children":158},{},[159],{"type":49,"value":160},"Proxy mechanism",{"type":43,"tag":153,"props":162,"children":163},{},[164,166,173],{"type":49,"value":165},"Same — ",{"type":43,"tag":167,"props":168,"children":170},"code",{"className":169},[],[171],{"type":49,"value":172},"delegatecall",{"type":49,"value":174}," to implementation contract",{"type":43,"tag":153,"props":176,"children":177},{},[178,183],{"type":43,"tag":167,"props":179,"children":181},{"className":180},[],[182],{"type":49,"value":172},{"type":49,"value":174},{"type":43,"tag":128,"props":185,"children":186},{},[187,195,206],{"type":43,"tag":153,"props":188,"children":189},{},[190],{"type":43,"tag":112,"props":191,"children":192},{},[193],{"type":49,"value":194},"Storage layout",{"type":43,"tag":153,"props":196,"children":197},{},[198,204],{"type":43,"tag":167,"props":199,"children":201},{"className":200},[],[202],{"type":49,"value":203},"#[storage]",{"type":49,"value":205}," fields map to the same EVM slots as equivalent Solidity structs",{"type":43,"tag":153,"props":207,"children":208},{},[209],{"type":49,"value":210},"Sequential slot allocation per Solidity rules",{"type":43,"tag":128,"props":212,"children":213},{},[214,222,227],{"type":43,"tag":153,"props":215,"children":216},{},[217],{"type":43,"tag":112,"props":218,"children":219},{},[220],{"type":49,"value":221},"EIP standards",{"type":43,"tag":153,"props":223,"children":224},{},[225],{"type":49,"value":226},"ERC-1967 storage slots, ERC-1822 proxiable UUID",{"type":43,"tag":153,"props":228,"children":229},{},[230],{"type":49,"value":231},"Same",{"type":43,"tag":128,"props":233,"children":234},{},[235,243,262],{"type":43,"tag":153,"props":236,"children":237},{},[238],{"type":43,"tag":112,"props":239,"children":240},{},[241],{"type":49,"value":242},"Context detection",{"type":43,"tag":153,"props":244,"children":245},{},[246,252,254,260],{"type":43,"tag":167,"props":247,"children":249},{"className":248},[],[250],{"type":49,"value":251},"logic_flag",{"type":49,"value":253}," boolean in a unique storage slot (no ",{"type":43,"tag":167,"props":255,"children":257},{"className":256},[],[258],{"type":49,"value":259},"immutable",{"type":49,"value":261}," support)",{"type":43,"tag":153,"props":263,"children":264},{},[265,271,273],{"type":43,"tag":167,"props":266,"children":268},{"className":267},[],[269],{"type":49,"value":270},"address(this)",{"type":49,"value":272}," stored as ",{"type":43,"tag":167,"props":274,"children":276},{"className":275},[],[277],{"type":49,"value":259},{"type":43,"tag":128,"props":279,"children":280},{},[281,289,309],{"type":43,"tag":153,"props":282,"children":283},{},[284],{"type":43,"tag":112,"props":285,"children":286},{},[287],{"type":49,"value":288},"Initialization",{"type":43,"tag":153,"props":290,"children":291},{},[292,294,299,301,307],{"type":49,"value":293},"Two-step: constructor sets ",{"type":43,"tag":167,"props":295,"children":297},{"className":296},[],[298],{"type":49,"value":251},{"type":49,"value":300},", then ",{"type":43,"tag":167,"props":302,"children":304},{"className":303},[],[305],{"type":49,"value":306},"set_version()",{"type":49,"value":308}," via proxy",{"type":43,"tag":153,"props":310,"children":311},{},[312],{"type":49,"value":313},"Constructor + initializer via proxy",{"type":43,"tag":128,"props":315,"children":316},{},[317,325,330],{"type":43,"tag":153,"props":318,"children":319},{},[320],{"type":43,"tag":112,"props":321,"children":322},{},[323],{"type":49,"value":324},"Reactivation",{"type":43,"tag":153,"props":326,"children":327},{},[328],{"type":49,"value":329},"WASM contracts must be reactivated every 365 days or after a Stylus protocol upgrade",{"type":43,"tag":153,"props":331,"children":332},{},[333],{"type":49,"value":334},"Not applicable",{"type":43,"tag":106,"props":336,"children":337},{},[338,340,345],{"type":49,"value":339},"Existing Solidity contracts can upgrade to a Stylus (Rust) implementation via proxy patterns. The ",{"type":43,"tag":167,"props":341,"children":343},{"className":342},[],[344],{"type":49,"value":203},{"type":49,"value":346}," macro lays out fields in the EVM state trie identically to Solidity, so storage slots line up when type definitions match.",{"type":43,"tag":52,"props":348,"children":350},{"id":349},"proxy-patterns",[351],{"type":49,"value":81},{"type":43,"tag":106,"props":353,"children":354},{},[355],{"type":49,"value":356},"OpenZeppelin Contracts for Stylus provides three proxy patterns:",{"type":43,"tag":120,"props":358,"children":359},{},[360,381],{"type":43,"tag":124,"props":361,"children":362},{},[363],{"type":43,"tag":128,"props":364,"children":365},{},[366,371,376],{"type":43,"tag":132,"props":367,"children":368},{},[369],{"type":49,"value":370},"Pattern",{"type":43,"tag":132,"props":372,"children":373},{},[374],{"type":49,"value":375},"Key types",{"type":43,"tag":132,"props":377,"children":378},{},[379],{"type":49,"value":380},"Best for",{"type":43,"tag":146,"props":382,"children":383},{},[384,424,456],{"type":43,"tag":128,"props":385,"children":386},{},[387,395,419],{"type":43,"tag":153,"props":388,"children":389},{},[390],{"type":43,"tag":112,"props":391,"children":392},{},[393],{"type":49,"value":394},"UUPS",{"type":43,"tag":153,"props":396,"children":397},{},[398,404,406,412,413],{"type":43,"tag":167,"props":399,"children":401},{"className":400},[],[402],{"type":49,"value":403},"UUPSUpgradeable",{"type":49,"value":405},", ",{"type":43,"tag":167,"props":407,"children":409},{"className":408},[],[410],{"type":49,"value":411},"IErc1822Proxiable",{"type":49,"value":405},{"type":43,"tag":167,"props":414,"children":416},{"className":415},[],[417],{"type":49,"value":418},"Erc1967Proxy",{"type":43,"tag":153,"props":420,"children":421},{},[422],{"type":49,"value":423},"Most projects — upgrade logic in the implementation, lighter proxy",{"type":43,"tag":128,"props":425,"children":426},{},[427,435,451],{"type":43,"tag":153,"props":428,"children":429},{},[430],{"type":43,"tag":112,"props":431,"children":432},{},[433],{"type":49,"value":434},"Beacon",{"type":43,"tag":153,"props":436,"children":437},{},[438,444,445],{"type":43,"tag":167,"props":439,"children":441},{"className":440},[],[442],{"type":49,"value":443},"BeaconProxy",{"type":49,"value":405},{"type":43,"tag":167,"props":446,"children":448},{"className":447},[],[449],{"type":49,"value":450},"UpgradeableBeacon",{"type":43,"tag":153,"props":452,"children":453},{},[454],{"type":49,"value":455},"Multiple proxies sharing one implementation — updating the beacon upgrades all proxies atomically",{"type":43,"tag":128,"props":457,"children":458},{},[459,467,482],{"type":43,"tag":153,"props":460,"children":461},{},[462],{"type":43,"tag":112,"props":463,"children":464},{},[465],{"type":49,"value":466},"Basic Proxy",{"type":43,"tag":153,"props":468,"children":469},{},[470,475,476],{"type":43,"tag":167,"props":471,"children":473},{"className":472},[],[474],{"type":49,"value":418},{"type":49,"value":405},{"type":43,"tag":167,"props":477,"children":479},{"className":478},[],[480],{"type":49,"value":481},"Erc1967Utils",{"type":43,"tag":153,"props":483,"children":484},{},[485],{"type":49,"value":486},"Low-level building block for custom proxy patterns",{"type":43,"tag":488,"props":489,"children":491},"h3",{"id":490},"uups",[492],{"type":49,"value":394},{"type":43,"tag":106,"props":494,"children":495},{},[496,498,503,505,510,512,518],{"type":49,"value":497},"The implementation contract composes ",{"type":43,"tag":167,"props":499,"children":501},{"className":500},[],[502],{"type":49,"value":403},{"type":49,"value":504}," in its ",{"type":43,"tag":167,"props":506,"children":508},{"className":507},[],[509],{"type":49,"value":203},{"type":49,"value":511}," struct alongside access control (e.g., ",{"type":43,"tag":167,"props":513,"children":515},{"className":514},[],[516],{"type":49,"value":517},"Ownable",{"type":49,"value":519},"). Integration requires:",{"type":43,"tag":521,"props":522,"children":523},"ol",{},[524,543,556,577,612],{"type":43,"tag":63,"props":525,"children":526},{},[527,529,534,536,541],{"type":49,"value":528},"Add ",{"type":43,"tag":167,"props":530,"children":532},{"className":531},[],[533],{"type":49,"value":403},{"type":49,"value":535}," (and access control) as fields in the ",{"type":43,"tag":167,"props":537,"children":539},{"className":538},[],[540],{"type":49,"value":203},{"type":49,"value":542}," struct",{"type":43,"tag":63,"props":544,"children":545},{},[546,548,554],{"type":49,"value":547},"Call ",{"type":43,"tag":167,"props":549,"children":551},{"className":550},[],[552],{"type":49,"value":553},"self.uups.constructor()",{"type":49,"value":555}," and initialize access control in the constructor",{"type":43,"tag":63,"props":557,"children":558},{},[559,561,567,569,575],{"type":49,"value":560},"Expose ",{"type":43,"tag":167,"props":562,"children":564},{"className":563},[],[565],{"type":49,"value":566},"initialize",{"type":49,"value":568}," calling ",{"type":43,"tag":167,"props":570,"children":572},{"className":571},[],[573],{"type":49,"value":574},"self.uups.set_version()",{"type":49,"value":576}," — invoked via proxy after deployment",{"type":43,"tag":63,"props":578,"children":579},{},[580,582,588,590,596,598,604,606],{"type":49,"value":581},"Implement ",{"type":43,"tag":167,"props":583,"children":585},{"className":584},[],[586],{"type":49,"value":587},"IUUPSUpgradeable",{"type":49,"value":589}," — ",{"type":43,"tag":167,"props":591,"children":593},{"className":592},[],[594],{"type":49,"value":595},"upgrade_to_and_call",{"type":49,"value":597}," guarded by access control, ",{"type":43,"tag":167,"props":599,"children":601},{"className":600},[],[602],{"type":49,"value":603},"upgrade_interface_version",{"type":49,"value":605}," delegating to ",{"type":43,"tag":167,"props":607,"children":609},{"className":608},[],[610],{"type":49,"value":611},"self.uups",{"type":43,"tag":63,"props":613,"children":614},{},[615,616,621,622,628,629],{"type":49,"value":581},{"type":43,"tag":167,"props":617,"children":619},{"className":618},[],[620],{"type":49,"value":411},{"type":49,"value":589},{"type":43,"tag":167,"props":623,"children":625},{"className":624},[],[626],{"type":49,"value":627},"proxiable_uuid",{"type":49,"value":605},{"type":43,"tag":167,"props":630,"children":632},{"className":631},[],[633],{"type":49,"value":611},{"type":43,"tag":106,"props":635,"children":636},{},[637,639,644,646,652],{"type":49,"value":638},"The proxy contract is a thin ",{"type":43,"tag":167,"props":640,"children":642},{"className":641},[],[643],{"type":49,"value":418},{"type":49,"value":645}," with a constructor that takes the implementation address and initialization data, and a ",{"type":43,"tag":167,"props":647,"children":649},{"className":648},[],[650],{"type":49,"value":651},"#[fallback]",{"type":49,"value":653}," handler that delegates all calls.",{"type":43,"tag":106,"props":655,"children":656},{},[657,659,665,667,673,675,681],{"type":49,"value":658},"Deploy the proxy with ",{"type":43,"tag":167,"props":660,"children":662},{"className":661},[],[663],{"type":49,"value":664},"set_version",{"type":49,"value":666}," as the initialization call data. Use ",{"type":43,"tag":167,"props":668,"children":670},{"className":669},[],[671],{"type":49,"value":672},"cargo stylus deploy",{"type":49,"value":674}," or a deployer contract. The initialization data is the ABI-encoded ",{"type":43,"tag":167,"props":676,"children":678},{"className":677},[],[679],{"type":49,"value":680},"setVersion",{"type":49,"value":682}," call:",{"type":43,"tag":684,"props":685,"children":689},"pre",{"className":686,"code":687,"language":21,"meta":688,"style":688},"language-rust shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","let data = MyContractAbi::setVersionCall {}.abi_encode();\n\u002F\u002F Pass `data` as the proxy constructor's second argument at deployment time.\n","",[690],{"type":43,"tag":167,"props":691,"children":692},{"__ignoreMap":688},[693,704],{"type":43,"tag":694,"props":695,"children":698},"span",{"class":696,"line":697},"line",1,[699],{"type":43,"tag":694,"props":700,"children":701},{},[702],{"type":49,"value":703},"let data = MyContractAbi::setVersionCall {}.abi_encode();\n",{"type":43,"tag":694,"props":705,"children":707},{"class":696,"line":706},2,[708],{"type":43,"tag":694,"props":709,"children":710},{},[711],{"type":49,"value":712},"\u002F\u002F Pass `data` as the proxy constructor's second argument at deployment time.\n",{"type":43,"tag":488,"props":714,"children":716},{"id":715},"beacon",[717],{"type":49,"value":434},{"type":43,"tag":106,"props":719,"children":720},{},[721,723,728,730,735],{"type":49,"value":722},"Multiple ",{"type":43,"tag":167,"props":724,"children":726},{"className":725},[],[727],{"type":49,"value":443},{"type":49,"value":729}," contracts point to a single ",{"type":43,"tag":167,"props":731,"children":733},{"className":732},[],[734],{"type":49,"value":450},{"type":49,"value":736}," that stores the current implementation address. Updating the beacon upgrades all proxies in one transaction.",{"type":43,"tag":488,"props":738,"children":740},{"id":739},"context-detection-stylus-specific",[741],{"type":49,"value":742},"Context detection (Stylus-specific)",{"type":43,"tag":106,"props":744,"children":745},{},[746,748,753,755,761,762,767,769,774],{"type":49,"value":747},"Stylus does not support the ",{"type":43,"tag":167,"props":749,"children":751},{"className":750},[],[752],{"type":49,"value":259},{"type":49,"value":754}," keyword. Instead of storing ",{"type":43,"tag":167,"props":756,"children":758},{"className":757},[],[759],{"type":49,"value":760},"__self = address(this)",{"type":49,"value":405},{"type":43,"tag":167,"props":763,"children":765},{"className":764},[],[766],{"type":49,"value":403},{"type":49,"value":768}," uses a ",{"type":43,"tag":167,"props":770,"children":772},{"className":771},[],[773],{"type":49,"value":251},{"type":49,"value":775}," boolean in a unique storage slot:",{"type":43,"tag":59,"props":777,"children":778},{},[779,799,819],{"type":43,"tag":63,"props":780,"children":781},{},[782,784,789,791,797],{"type":49,"value":783},"The implementation's ",{"type":43,"tag":112,"props":785,"children":786},{},[787],{"type":49,"value":788},"constructor",{"type":49,"value":790}," sets ",{"type":43,"tag":167,"props":792,"children":794},{"className":793},[],[795],{"type":49,"value":796},"logic_flag = true",{"type":49,"value":798}," in its own storage.",{"type":43,"tag":63,"props":800,"children":801},{},[802,804,809,811,817],{"type":49,"value":803},"When code runs via a proxy (",{"type":43,"tag":167,"props":805,"children":807},{"className":806},[],[808],{"type":49,"value":172},{"type":49,"value":810},"), the proxy's storage does not contain this flag, so it reads as ",{"type":43,"tag":167,"props":812,"children":814},{"className":813},[],[815],{"type":49,"value":816},"false",{"type":49,"value":818},".",{"type":43,"tag":63,"props":820,"children":821},{},[822,828],{"type":43,"tag":167,"props":823,"children":825},{"className":824},[],[826],{"type":49,"value":827},"only_proxy()",{"type":49,"value":829}," checks this flag to ensure upgrade functions can only be called through the proxy, not directly on the implementation.",{"type":43,"tag":106,"props":831,"children":832},{},[833,838,840,846],{"type":43,"tag":167,"props":834,"children":836},{"className":835},[],[837],{"type":49,"value":827},{"type":49,"value":839}," also verifies that the ERC-1967 implementation slot is non-zero and that the proxy-stored version matches the implementation's ",{"type":43,"tag":167,"props":841,"children":843},{"className":842},[],[844],{"type":49,"value":845},"VERSION_NUMBER",{"type":49,"value":818},{"type":43,"tag":848,"props":849,"children":850},"blockquote",{},[851],{"type":43,"tag":106,"props":852,"children":853},{},[854,859,861,867,869,877],{"type":43,"tag":112,"props":855,"children":856},{},[857],{"type":49,"value":858},"Examples:",{"type":49,"value":860}," See the ",{"type":43,"tag":167,"props":862,"children":864},{"className":863},[],[865],{"type":49,"value":866},"examples\u002F",{"type":49,"value":868}," directory of the ",{"type":43,"tag":67,"props":870,"children":874},{"href":871,"rel":872},"https:\u002F\u002Fgithub.com\u002FOpenZeppelin\u002Frust-contracts-stylus",[873],"nofollow",[875],{"type":49,"value":876},"rust-contracts-stylus repository",{"type":49,"value":878}," for full working integration examples of UUPS, Beacon, and related patterns.",{"type":43,"tag":52,"props":880,"children":882},{"id":881},"access-control",[883],{"type":49,"value":90},{"type":43,"tag":106,"props":885,"children":886},{},[887,889,894,896,901],{"type":49,"value":888},"Upgrade functions must be guarded with access control. OpenZeppelin's Stylus contracts do ",{"type":43,"tag":112,"props":890,"children":891},{},[892],{"type":49,"value":893},"not",{"type":49,"value":895}," embed access control into the upgrade logic itself — you must add it in ",{"type":43,"tag":167,"props":897,"children":899},{"className":898},[],[900],{"type":49,"value":595},{"type":49,"value":902},":",{"type":43,"tag":684,"props":904,"children":906},{"className":686,"code":905,"language":21,"meta":688,"style":688},"fn upgrade_to_and_call(&mut self, new_implementation: Address, data: Bytes) -> Result\u003C(), Vec\u003Cu8>> {\n    self.ownable.only_owner()?; \u002F\u002F or any access control check\n    self.uups.upgrade_to_and_call(new_implementation, data)?;\n    Ok(())\n}\n",[907],{"type":43,"tag":167,"props":908,"children":909},{"__ignoreMap":688},[910,918,926,935,944],{"type":43,"tag":694,"props":911,"children":912},{"class":696,"line":697},[913],{"type":43,"tag":694,"props":914,"children":915},{},[916],{"type":49,"value":917},"fn upgrade_to_and_call(&mut self, new_implementation: Address, data: Bytes) -> Result\u003C(), Vec\u003Cu8>> {\n",{"type":43,"tag":694,"props":919,"children":920},{"class":696,"line":706},[921],{"type":43,"tag":694,"props":922,"children":923},{},[924],{"type":49,"value":925},"    self.ownable.only_owner()?; \u002F\u002F or any access control check\n",{"type":43,"tag":694,"props":927,"children":929},{"class":696,"line":928},3,[930],{"type":43,"tag":694,"props":931,"children":932},{},[933],{"type":49,"value":934},"    self.uups.upgrade_to_and_call(new_implementation, data)?;\n",{"type":43,"tag":694,"props":936,"children":938},{"class":696,"line":937},4,[939],{"type":43,"tag":694,"props":940,"children":941},{},[942],{"type":49,"value":943},"    Ok(())\n",{"type":43,"tag":694,"props":945,"children":947},{"class":696,"line":946},5,[948],{"type":43,"tag":694,"props":949,"children":950},{},[951],{"type":49,"value":952},"}\n",{"type":43,"tag":106,"props":954,"children":955},{},[956],{"type":49,"value":957},"Common options:",{"type":43,"tag":59,"props":959,"children":960},{},[961,970,980],{"type":43,"tag":63,"props":962,"children":963},{},[964,968],{"type":43,"tag":112,"props":965,"children":966},{},[967],{"type":49,"value":517},{"type":49,"value":969}," — single owner, simplest pattern",{"type":43,"tag":63,"props":971,"children":972},{},[973,978],{"type":43,"tag":112,"props":974,"children":975},{},[976],{"type":49,"value":977},"AccessControl \u002F RBAC",{"type":49,"value":979}," — role-based, finer granularity",{"type":43,"tag":63,"props":981,"children":982},{},[983,988],{"type":43,"tag":112,"props":984,"children":985},{},[986],{"type":49,"value":987},"Multisig or governance",{"type":49,"value":989}," — for production contracts managing significant value",{"type":43,"tag":52,"props":991,"children":993},{"id":992},"upgrade-safety",[994],{"type":49,"value":99},{"type":43,"tag":488,"props":996,"children":998},{"id":997},"storage-compatibility",[999],{"type":49,"value":1000},"Storage compatibility",{"type":43,"tag":106,"props":1002,"children":1003},{},[1004,1006,1011],{"type":49,"value":1005},"Stylus ",{"type":43,"tag":167,"props":1007,"children":1009},{"className":1008},[],[1010],{"type":49,"value":203},{"type":49,"value":1012}," fields are laid out in the EVM state trie identically to Solidity. The same storage layout rules apply when upgrading:",{"type":43,"tag":59,"props":1014,"children":1015},{},[1016,1026,1035,1045],{"type":43,"tag":63,"props":1017,"children":1018},{},[1019,1024],{"type":43,"tag":112,"props":1020,"children":1021},{},[1022],{"type":49,"value":1023},"Never",{"type":49,"value":1025}," reorder, remove, or change the type of existing storage fields",{"type":43,"tag":63,"props":1027,"children":1028},{},[1029,1033],{"type":43,"tag":112,"props":1030,"children":1031},{},[1032],{"type":49,"value":1023},{"type":49,"value":1034}," insert new fields before existing ones",{"type":43,"tag":63,"props":1036,"children":1037},{},[1038,1043],{"type":43,"tag":112,"props":1039,"children":1040},{},[1041],{"type":49,"value":1042},"Only",{"type":49,"value":1044}," append new fields at the end of the struct",{"type":43,"tag":63,"props":1046,"children":1047},{},[1048],{"type":49,"value":1049},"ERC-1967 proxy storage slots are in high, standardized locations — they will not collide with implementation storage",{"type":43,"tag":106,"props":1051,"children":1052},{},[1053,1055,1060,1062,1068,1069,1074,1075,1080],{"type":49,"value":1054},"One difference from Solidity: nested structs in Stylus ",{"type":43,"tag":167,"props":1056,"children":1058},{"className":1057},[],[1059],{"type":49,"value":203},{"type":49,"value":1061}," (e.g., composing ",{"type":43,"tag":167,"props":1063,"children":1065},{"className":1064},[],[1066],{"type":49,"value":1067},"Erc20",{"type":49,"value":405},{"type":43,"tag":167,"props":1070,"children":1072},{"className":1071},[],[1073],{"type":49,"value":517},{"type":49,"value":405},{"type":43,"tag":167,"props":1076,"children":1078},{"className":1077},[],[1079],{"type":49,"value":403},{"type":49,"value":1081}," as fields) are laid out with each nested struct starting at its own deterministic slot. This is consistent with regular struct nesting in Solidity, but not with Solidity's inheritance-based flat layout where all inherited variables share a single sequential slot range.",{"type":43,"tag":488,"props":1083,"children":1085},{"id":1084},"initialization-safety",[1086],{"type":49,"value":1087},"Initialization safety",{"type":43,"tag":59,"props":1089,"children":1090},{},[1091,1108,1132,1144],{"type":43,"tag":63,"props":1092,"children":1093},{},[1094,1096,1100,1101,1106],{"type":49,"value":1095},"The implementation ",{"type":43,"tag":112,"props":1097,"children":1098},{},[1099],{"type":49,"value":788},{"type":49,"value":790},{"type":43,"tag":167,"props":1102,"children":1104},{"className":1103},[],[1105],{"type":49,"value":251},{"type":49,"value":1107}," and any implementation-only state. It runs once at implementation deployment.",{"type":43,"tag":63,"props":1109,"children":1110},{},[1111,1116,1118,1123,1125,1130],{"type":43,"tag":167,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":49,"value":306},{"type":49,"value":1117}," must be called via the proxy (during deployment or via ",{"type":43,"tag":167,"props":1119,"children":1121},{"className":1120},[],[1122],{"type":49,"value":595},{"type":49,"value":1124},") to write the ",{"type":43,"tag":167,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":49,"value":845},{"type":49,"value":1131}," into the proxy's storage.",{"type":43,"tag":63,"props":1133,"children":1134},{},[1135,1137,1142],{"type":49,"value":1136},"If additional initialization is needed (ownership, token supply), expose a protected initialization function and include ",{"type":43,"tag":167,"props":1138,"children":1140},{"className":1139},[],[1141],{"type":49,"value":306},{"type":49,"value":1143}," in it.",{"type":43,"tag":63,"props":1145,"children":1146},{},[1147],{"type":49,"value":1148},"Failing to initialize properly can result in orphaned contracts with no owner, uninitialized state, or denied future upgrades.",{"type":43,"tag":488,"props":1150,"children":1152},{"id":1151},"uups-upgrade-checks",[1153],{"type":49,"value":1154},"UUPS upgrade checks",{"type":43,"tag":106,"props":1156,"children":1157},{},[1158],{"type":49,"value":1159},"The UUPS implementation enforces three safety checks:",{"type":43,"tag":521,"props":1161,"children":1162},{},[1163,1188,1209],{"type":43,"tag":63,"props":1164,"children":1165},{},[1166,1171,1173,1178,1180,1186],{"type":43,"tag":112,"props":1167,"children":1168},{},[1169],{"type":49,"value":1170},"Access control",{"type":49,"value":1172}," — restrict ",{"type":43,"tag":167,"props":1174,"children":1176},{"className":1175},[],[1177],{"type":49,"value":595},{"type":49,"value":1179}," (e.g., ",{"type":43,"tag":167,"props":1181,"children":1183},{"className":1182},[],[1184],{"type":49,"value":1185},"self.ownable.only_owner()",{"type":49,"value":1187},")",{"type":43,"tag":63,"props":1189,"children":1190},{},[1191,1196,1197,1202,1204],{"type":43,"tag":112,"props":1192,"children":1193},{},[1194],{"type":49,"value":1195},"Proxy context enforcement",{"type":49,"value":589},{"type":43,"tag":167,"props":1198,"children":1200},{"className":1199},[],[1201],{"type":49,"value":827},{"type":49,"value":1203}," reverts if the call is not via ",{"type":43,"tag":167,"props":1205,"children":1207},{"className":1206},[],[1208],{"type":49,"value":172},{"type":43,"tag":63,"props":1210,"children":1211},{},[1212,1217,1218,1224],{"type":43,"tag":112,"props":1213,"children":1214},{},[1215],{"type":49,"value":1216},"Proxiable UUID validation",{"type":49,"value":589},{"type":43,"tag":167,"props":1219,"children":1221},{"className":1220},[],[1222],{"type":49,"value":1223},"proxiable_uuid()",{"type":49,"value":1225}," must return the ERC-1967 implementation slot, confirming UUPS compatibility",{"type":43,"tag":488,"props":1227,"children":1229},{"id":1228},"reactivation",[1230],{"type":49,"value":324},{"type":43,"tag":106,"props":1232,"children":1233},{},[1234,1236,1241,1243,1249,1251,1257],{"type":49,"value":1235},"Stylus WASM contracts must be ",{"type":43,"tag":112,"props":1237,"children":1238},{},[1239],{"type":49,"value":1240},"reactivated once per year",{"type":49,"value":1242}," (365 days) or after any Stylus protocol upgrade. Reactivation can be done using ",{"type":43,"tag":167,"props":1244,"children":1246},{"className":1245},[],[1247],{"type":49,"value":1248},"cargo-stylus",{"type":49,"value":1250}," or the ",{"type":43,"tag":167,"props":1252,"children":1254},{"className":1253},[],[1255],{"type":49,"value":1256},"ArbWasm",{"type":49,"value":1258}," precompile. If a contract is not reactivated, it becomes uncallable. This is orthogonal to proxy upgrades but must be factored into maintenance planning.",{"type":43,"tag":488,"props":1260,"children":1262},{"id":1261},"testing-upgrade-paths",[1263],{"type":49,"value":1264},"Testing upgrade paths",{"type":43,"tag":106,"props":1266,"children":1267},{},[1268],{"type":49,"value":1269},"Before upgrading a production contract:",{"type":43,"tag":59,"props":1271,"children":1274},{"className":1272},[1273],"contains-task-list",[1275,1295,1317,1332,1352,1367,1387,1402],{"type":43,"tag":63,"props":1276,"children":1279},{"className":1277},[1278],"task-list-item",[1280,1286,1288,1293],{"type":43,"tag":1281,"props":1282,"children":1285},"input",{"disabled":1283,"type":1284},true,"checkbox",[],{"type":49,"value":1287}," ",{"type":43,"tag":112,"props":1289,"children":1290},{},[1291],{"type":49,"value":1292},"Deploy V1 implementation and proxy",{"type":49,"value":1294}," on a local Arbitrum devnet",{"type":43,"tag":63,"props":1296,"children":1298},{"className":1297},[1278],[1299,1302,1303,1308,1310,1315],{"type":43,"tag":1281,"props":1300,"children":1301},{"disabled":1283,"type":1284},[],{"type":49,"value":1287},{"type":43,"tag":112,"props":1304,"children":1305},{},[1306],{"type":49,"value":1307},"Write state with V1",{"type":49,"value":1309},", upgrade to V2 via ",{"type":43,"tag":167,"props":1311,"children":1313},{"className":1312},[],[1314],{"type":49,"value":595},{"type":49,"value":1316},", and verify that all existing state reads correctly",{"type":43,"tag":63,"props":1318,"children":1320},{"className":1319},[1278],[1321,1324,1325,1330],{"type":43,"tag":1281,"props":1322,"children":1323},{"disabled":1283,"type":1284},[],{"type":49,"value":1287},{"type":43,"tag":112,"props":1326,"children":1327},{},[1328],{"type":49,"value":1329},"Verify new functionality",{"type":49,"value":1331}," works as expected after the upgrade",{"type":43,"tag":63,"props":1333,"children":1335},{"className":1334},[1278],[1336,1339,1340,1345,1347],{"type":43,"tag":1281,"props":1337,"children":1338},{"disabled":1283,"type":1284},[],{"type":49,"value":1287},{"type":43,"tag":112,"props":1341,"children":1342},{},[1343],{"type":49,"value":1344},"Confirm access control",{"type":49,"value":1346}," — only authorized callers can invoke ",{"type":43,"tag":167,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":49,"value":595},{"type":43,"tag":63,"props":1353,"children":1355},{"className":1354},[1278],[1356,1359,1360,1365],{"type":43,"tag":1281,"props":1357,"children":1358},{"disabled":1283,"type":1284},[],{"type":49,"value":1287},{"type":43,"tag":112,"props":1361,"children":1362},{},[1363],{"type":49,"value":1364},"Check storage layout",{"type":49,"value":1366}," — ensure no reordering, removal, or type changes to existing fields",{"type":43,"tag":63,"props":1368,"children":1370},{"className":1369},[1278],[1371,1374,1375,1385],{"type":43,"tag":1281,"props":1372,"children":1373},{"disabled":1283,"type":1284},[],{"type":49,"value":1287},{"type":43,"tag":112,"props":1376,"children":1377},{},[1378,1380],{"type":49,"value":1379},"Verify ",{"type":43,"tag":167,"props":1381,"children":1383},{"className":1382},[],[1384],{"type":49,"value":845},{"type":49,"value":1386}," is incremented in the new implementation",{"type":43,"tag":63,"props":1388,"children":1390},{"className":1389},[1278],[1391,1394,1395,1400],{"type":43,"tag":1281,"props":1392,"children":1393},{"disabled":1283,"type":1284},[],{"type":49,"value":1287},{"type":43,"tag":112,"props":1396,"children":1397},{},[1398],{"type":49,"value":1399},"Test reactivation",{"type":49,"value":1401}," — ensure the upgraded contract can be reactivated",{"type":43,"tag":63,"props":1403,"children":1405},{"className":1404},[1278],[1406,1409,1410,1415],{"type":43,"tag":1281,"props":1407,"children":1408},{"disabled":1283,"type":1284},[],{"type":49,"value":1287},{"type":43,"tag":112,"props":1411,"children":1412},{},[1413],{"type":49,"value":1414},"Manual review",{"type":49,"value":1416}," — there is no automated storage layout validation for Stylus Rust contracts; rely on struct comparison and devnet testing",{"type":43,"tag":1418,"props":1419,"children":1420},"style",{},[1421],{"type":49,"value":1422},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1424,"total":1551},[1425,1439,1454,1466,1479,1489,1499,1512,1522,1533,1544],{"slug":1426,"name":1426,"fn":1427,"description":1428,"org":1429,"tags":1430,"stars":25,"repoUrl":26,"updatedAt":1438},"develop-secure-contracts","develop secure smart contracts with OpenZeppelin","Develop secure smart contracts using OpenZeppelin Contracts libraries. Use when users need to integrate OpenZeppelin library components — including token standards (ERC20, ERC721, ERC1155), access control (Ownable, AccessControl, AccessManager), security primitives (Pausable, ReentrancyGuard), governance (Governor, timelocks), or accounts (multisig, account abstraction) — into existing or new contracts. Covers pattern discovery from library source, CLI contract generators, and library-first integration. Supports Solidity, Cairo, Stylus, Stellar, and Sui Move.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1431,1432,1435,1436],{"name":90,"slug":881,"type":15},{"name":1433,"slug":1434,"type":15},"Security","security",{"name":23,"slug":24,"type":15},{"name":144,"slug":1437,"type":15},"solidity","2026-07-13T06:04:32.666273",{"slug":1440,"name":1440,"fn":1441,"description":1442,"org":1443,"tags":1444,"stars":25,"repoUrl":26,"updatedAt":1453},"review-sui-contracts","review Sui Move smart contracts","Review Sui Move code that integrates OpenZeppelin Contracts for Sui against the library's own patterns and conventions. Use this when a developer wants their integration checked before shipping. Triggers: \"review my Sui Move code\", \"am I using OpenZeppelin correctly\", \"check this integration\", \"is this idiomatic\", \"review before audit\". Checks correct use of OZ primitives, deviations from examples\u002Fdoc-comments, upheld invariants, test coverage, and code-quality\u002Fstyle. This is an AI code review, not a formal security audit.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1445,1448,1451,1452],{"name":1446,"slug":1447,"type":15},"Blockchain","blockchain",{"name":1449,"slug":1450,"type":15},"Code Review","code-review",{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},"2026-07-16T06:00:49.17387",{"slug":1455,"name":1455,"fn":1456,"description":1457,"org":1458,"tags":1459,"stars":25,"repoUrl":26,"updatedAt":1465},"setup-cairo-contracts","set up Cairo smart contract projects","Set up a Cairo smart contract project with OpenZeppelin Contracts for Cairo on Starknet. Use when users need to: (1) create a new Scarb\u002FStarknet project, (2) add OpenZeppelin Contracts for Cairo dependencies to Scarb.toml, (3) configure individual or umbrella OpenZeppelin packages, or (4) understand Cairo import conventions and component patterns for OpenZeppelin.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1460,1463,1464],{"name":1461,"slug":1462,"type":15},"Engineering","engineering",{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},"2026-07-13T06:04:17.186825",{"slug":1467,"name":1467,"fn":1468,"description":1469,"org":1470,"tags":1471,"stars":25,"repoUrl":26,"updatedAt":1478},"setup-solidity-contracts","set up Solidity smart contract projects","Set up a Solidity smart contract project with OpenZeppelin Contracts. Use when users need to: (1) create a new Hardhat or Foundry project, (2) install OpenZeppelin Contracts dependencies for Solidity, (3) configure remappings for Foundry, or (4) understand Solidity import conventions for OpenZeppelin.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1472,1473,1476,1477],{"name":1461,"slug":1462,"type":15},{"name":1474,"slug":1475,"type":15},"Foundry","foundry",{"name":23,"slug":24,"type":15},{"name":144,"slug":1437,"type":15},"2026-07-13T06:04:29.360325",{"slug":1480,"name":1480,"fn":1481,"description":1482,"org":1483,"tags":1484,"stars":25,"repoUrl":26,"updatedAt":1488},"setup-stellar-contracts","set up Stellar Soroban smart contract projects","Set up a Stellar\u002FSoroban smart contract project with OpenZeppelin Contracts for Stellar. Use when users need to: (1) install Stellar CLI and Rust toolchain for Soroban, (2) create a new Soroban project, (3) add OpenZeppelin Stellar dependencies to Cargo.toml, or (4) understand Soroban import conventions and contract patterns for OpenZeppelin.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1485,1486,1487],{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},"2026-07-13T06:04:23.807685",{"slug":1490,"name":1490,"fn":1491,"description":1492,"org":1493,"tags":1494,"stars":25,"repoUrl":26,"updatedAt":1498},"setup-stylus-contracts","set up Stylus smart contract projects","Set up a Stylus smart contract project with OpenZeppelin Contracts for Stylus on Arbitrum. Use when users need to: (1) install Rust toolchain and WASM target for Stylus, (2) create a new Cargo Stylus project, (3) add OpenZeppelin Stylus dependencies to Cargo.toml, or (4) understand Stylus import conventions and storage patterns for OpenZeppelin.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1495,1496,1497],{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},"2026-07-13T06:04:18.638516",{"slug":1500,"name":1500,"fn":1501,"description":1502,"org":1503,"tags":1504,"stars":25,"repoUrl":26,"updatedAt":1511},"setup-sui-contracts","set up Sui Move smart contracts","Set up a Sui Move smart contract project with OpenZeppelin Contracts for Sui. Use when users need to: (1) install the Sui CLI and Move toolchain, (2) create a new Sui Move package, (3) discover and add OpenZeppelin Sui dependencies to Move.toml via the Move Registry (MVR), (4) learn the integration pattern from the library's examples and API docs before implementing, or (5) understand Sui Move import conventions and build\u002Ftest commands for OpenZeppelin.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1505,1506,1509,1510],{"name":1446,"slug":1447,"type":15},{"name":1507,"slug":1508,"type":15},"CLI","cli",{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},"2026-07-16T05:59:21.671811",{"slug":1513,"name":1513,"fn":1514,"description":1515,"org":1516,"tags":1517,"stars":25,"repoUrl":26,"updatedAt":1521},"upgrade-cairo-contracts","upgrade Cairo smart contracts on Starknet","Upgrade Cairo smart contracts using OpenZeppelin's UpgradeableComponent on Starknet. Use when users need to: (1) make Cairo contracts upgradeable via replace_class_syscall, (2) integrate the OpenZeppelin UpgradeableComponent, (3) understand Starknet's class-based upgrade model vs EVM proxy patterns, (4) ensure storage compatibility across upgrades, (5) guard upgrade functions with access control, or (6) test upgrade paths for Cairo contracts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1518,1519,1520],{"name":17,"slug":18,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},"2026-07-13T06:04:25.126377",{"slug":1523,"name":1523,"fn":1524,"description":1525,"org":1526,"tags":1527,"stars":25,"repoUrl":26,"updatedAt":1532},"upgrade-solidity-contracts","upgrade Solidity smart contracts with proxies","Upgrade Solidity smart contracts using OpenZeppelin proxy patterns. Use when users need to: (1) make contracts upgradeable with UUPS, Transparent, or Beacon proxies, (2) write initializers instead of constructors, (3) use the Hardhat or Foundry upgrades plugins, (4) understand storage layout rules and ERC-7201 namespaced storage, (5) validate upgrade safety, (6) manage proxy deployments and upgrades, or (7) understand upgrade restrictions between OpenZeppelin Contracts major versions.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1528,1529,1530,1531],{"name":17,"slug":18,"type":15},{"name":1433,"slug":1434,"type":15},{"name":23,"slug":24,"type":15},{"name":144,"slug":1437,"type":15},"2026-07-13T06:04:20.958319",{"slug":1534,"name":1534,"fn":1535,"description":1536,"org":1537,"tags":1538,"stars":25,"repoUrl":26,"updatedAt":1543},"upgrade-stellar-contracts","upgrade Stellar Soroban smart contracts","Upgrade Stellar\u002FSoroban smart contracts using OpenZeppelin's upgradeable module. Use when users need to: (1) make Soroban contracts upgradeable via native WASM replacement, (2) use Upgradeable or UpgradeableMigratable derive macros, (3) implement atomic upgrade-and-migrate patterns with an Upgrader contract, (4) ensure storage key compatibility across upgrades, or (5) test upgrade paths for Soroban contracts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1539,1540,1541,1542],{"name":1446,"slug":1447,"type":15},{"name":17,"slug":18,"type":15},{"name":1433,"slug":1434,"type":15},{"name":23,"slug":24,"type":15},"2026-07-13T06:04:31.398663",{"slug":4,"name":4,"fn":5,"description":6,"org":1545,"tags":1546,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1547,1548,1549,1550],{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},11,{"items":1553,"total":1551},[1554,1561,1568,1574,1581,1587,1593],{"slug":1426,"name":1426,"fn":1427,"description":1428,"org":1555,"tags":1556,"stars":25,"repoUrl":26,"updatedAt":1438},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1557,1558,1559,1560],{"name":90,"slug":881,"type":15},{"name":1433,"slug":1434,"type":15},{"name":23,"slug":24,"type":15},{"name":144,"slug":1437,"type":15},{"slug":1440,"name":1440,"fn":1441,"description":1442,"org":1562,"tags":1563,"stars":25,"repoUrl":26,"updatedAt":1453},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1564,1565,1566,1567],{"name":1446,"slug":1447,"type":15},{"name":1449,"slug":1450,"type":15},{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"slug":1455,"name":1455,"fn":1456,"description":1457,"org":1569,"tags":1570,"stars":25,"repoUrl":26,"updatedAt":1465},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1571,1572,1573],{"name":1461,"slug":1462,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},{"slug":1467,"name":1467,"fn":1468,"description":1469,"org":1575,"tags":1576,"stars":25,"repoUrl":26,"updatedAt":1478},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1577,1578,1579,1580],{"name":1461,"slug":1462,"type":15},{"name":1474,"slug":1475,"type":15},{"name":23,"slug":24,"type":15},{"name":144,"slug":1437,"type":15},{"slug":1480,"name":1480,"fn":1481,"description":1482,"org":1582,"tags":1583,"stars":25,"repoUrl":26,"updatedAt":1488},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1584,1585,1586],{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},{"slug":1490,"name":1490,"fn":1491,"description":1492,"org":1588,"tags":1589,"stars":25,"repoUrl":26,"updatedAt":1498},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1590,1591,1592],{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},{"slug":1500,"name":1500,"fn":1501,"description":1502,"org":1594,"tags":1595,"stars":25,"repoUrl":26,"updatedAt":1511},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1596,1597,1598,1599],{"name":1446,"slug":1447,"type":15},{"name":1507,"slug":1508,"type":15},{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15}]