From 56a9c2440f3e0ad0c421c1c67d4eb359eca781c7 Mon Sep 17 00:00:00 2001 From: Marcos Carlomagno Date: Fri, 2 Aug 2024 10:51:06 -0300 Subject: [PATCH] docs: add uups upgrade example (#499) * add uups upgrade example * fix readme * update lock file + remove unused config * Update examples/upgrade-contract-uups/README.md Co-authored-by: Nami * Update examples/upgrade-contract-uups/README.md Co-authored-by: Nami --------- Co-authored-by: Nami --- examples/upgrade-contract-uups/README.md | 22 ++ .../abis/UUPSOwnable.json | 222 ++++++++++++++++++ examples/upgrade-contract-uups/index.js | 25 ++ examples/upgrade-contract-uups/package.json | 15 ++ pnpm-lock.yaml | 9 + 5 files changed, 293 insertions(+) create mode 100644 examples/upgrade-contract-uups/README.md create mode 100644 examples/upgrade-contract-uups/abis/UUPSOwnable.json create mode 100644 examples/upgrade-contract-uups/index.js create mode 100644 examples/upgrade-contract-uups/package.json diff --git a/examples/upgrade-contract-uups/README.md b/examples/upgrade-contract-uups/README.md new file mode 100644 index 00000000..5018cea9 --- /dev/null +++ b/examples/upgrade-contract-uups/README.md @@ -0,0 +1,22 @@ +## Defender SDK upgrade + +This example showcases a simple contract upgrade using UUPS + ownable. + +### Steps to run this example + +1. Create a deployment environment for the sepolia network, (https://docs.openzeppelin.com/defender/v2/tutorial/deploy#environment_setup)[see how] +2. Go to https://wizard.openzeppelin.com/#custom +3. Select Ownable + UUPS upgradeablity. +4. Deploy the contract AND the proxy. +5. Use the deployed contract addresses as follows: + +```js +const upgrade = await client.deploy.upgradeContract({ + proxyAddress: '0x3a...ad7', // erc1967 proxy address + newImplementationAddress: '0x484...99', // address of the new implementation contract + newImplementationABI: JSON.stringify(uupsOwnableAbi), // The ABI of the new implementation (must implement UUPS standard) + network: 'sepolia', +}); +``` + +6. Go to your Defender dashboard to see the status of your upgrade. diff --git a/examples/upgrade-contract-uups/abis/UUPSOwnable.json b/examples/upgrade-contract-uups/abis/UUPSOwnable.json new file mode 100644 index 00000000..d8123825 --- /dev/null +++ b/examples/upgrade-contract-uups/abis/UUPSOwnable.json @@ -0,0 +1,222 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/examples/upgrade-contract-uups/index.js b/examples/upgrade-contract-uups/index.js new file mode 100644 index 00000000..34eb69a5 --- /dev/null +++ b/examples/upgrade-contract-uups/index.js @@ -0,0 +1,25 @@ +require('dotenv').config(); + +const { Defender } = require('@openzeppelin/defender-sdk'); + +const uupsOwnableAbi = require('./abis/UUPSOwnable.json'); + +async function main() { + const client = new Defender({ + apiKey: process.env.API_KEY, + apiSecret: process.env.API_SECRET, + }); + + const upgrade = await client.deploy.upgradeContract({ + proxyAddress: '0x3a...d7', + newImplementationAddress: '0x48...99', + newImplementationABI: JSON.stringify(uupsOwnableAbi), + network: 'sepolia', + }); + + console.log(upgrade); +} + +if (require.main === module) { + main().catch(console.error); +} diff --git a/examples/upgrade-contract-uups/package.json b/examples/upgrade-contract-uups/package.json new file mode 100644 index 00000000..5cee42df --- /dev/null +++ b/examples/upgrade-contract-uups/package.json @@ -0,0 +1,15 @@ +{ + "name": "@openzeppelin/defender-sdk-example-upgrade-contract-uups", + "version": "1.14.2", + "private": true, + "main": "index.js", + "author": "Openzeppelin Defender ", + "license": "MIT", + "scripts": { + "start": "node index.js" + }, + "dependencies": { + "@openzeppelin/defender-sdk": "1.14.2", + "dotenv": "^16.3.1" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3b52859..3f88df01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -383,6 +383,15 @@ importers: specifier: ^16.3.1 version: 16.4.5 + examples/upgrade-contract-uups: + dependencies: + '@openzeppelin/defender-sdk': + specifier: 1.14.2 + version: link:../../packages/defender-sdk + dotenv: + specifier: ^16.3.1 + version: 16.4.5 + examples/webhook-notification: dependencies: '@openzeppelin/defender-sdk':