1 of 33

2 of 33

Brief overview

of the workshop agenda

3 of 33

What are

Smart Contracts?

4 of 33

Reasons for upgrading smart contracts 🔄

5 of 33

Upgradeability Challenges

Key challenges in upgrading smart contracts ⚠️

Immutability of blockchain ⚠️

Need to preserve contract state and address.

​

​

6 of 33

Proxy Pattern

Introduction to the Proxy Pattern 🛡️

7 of 33

Proxy Types

Different types of proxies (e.g., Transparent Proxy, UUPS Proxy, Beacon Proxy) 📑.

8 of 33

Transparent

Proxy Pattern

9 of 33

UUPS

Proxy Pattern

10 of 33

Beacon

Proxy Pattern

11 of 33

Diamond Standard

12 of 33

Implementing Proxies

in Solidity

13 of 33

Solidity Code Example - Transparent Proxy

14 of 33

Introduction to ink!

and its proxy pattern 🦀

15 of 33

ink!

Code Example - Proxy

16 of 33

Introduction to OpenZeppelin and OpenBrush libraries 📚

17 of 33

⚠️ WARNING: OpenBrush is no longer actively maintained

18 of 33

19 of 33

Using OpenZeppelin for

upgradeable contracts 🏗️

20 of 33

Solidity Code Example - UUPS Proxy

21 of 33

OpenBrush Upgradeable Contracts

Using OpenBrush for upgradeable contracts 🦀.

22 of 33

ink! Code Example

| OpenBrush

23 of 33

🦄 Uniswap Example - Need for Upgrades

24 of 33

Uniswap V1 to V2 Upgrade

Transition from Uniswap V1 to V2 🚀.

25 of 33

Uniswap V2 to V3 Upgrade

Transition from Uniswap V2 to V3 🔄

26 of 33

Best Practices for

Upgradeable Contracts

Recommended practices for implementing upgradeable contracts 🌟

27 of 33

Testing Upgradable Contracts

Importance of testing upgradeable contracts 🧪

28 of 33

Security Considerations

Key security considerations for upgradeable contracts 🔒

29 of 33

Proxy Misuse and Security Incidents

  • Proxy Admin Key Compromise
  • PAID Network was exploited
  • Uninitialized UUPS Proxy Implementation
    • Parity Multisig Freeze
    • Harvest Finance, Teller, KeeperDAO, and Rivermen NFT all used uninitialized contracts that would allowed attackers to set initialization parameters pointing to a contract and execute selfdestruct() during a delegatecall().
  • Storage Collision
    • The Audius governance hack
  • delegatecall() or call to an Untrusted Contract
    • Pickle Finance and Furucombo, dYdX

30 of 33

Best Practices

  • General
    • Integrate Proxy Pattern Only When Necessary
    • Do Not Modify the Proxy Library
  • Operational
    • Initialize the Logic Contract
    • Secure the Proxy Admin Account
    • Use a Separate Account for the Transparent Proxy Admin
  • Contract Storage
    • Be Cautious when Declaring State Variables in Proxy Contracts
    • Maintain the Logic Contract's Variable Declaration Order and Type
    • Include Storage Gap in Base Contracts
    • No State Variable Assignment During Construction or Declaration

31 of 33

Best Practices

  • Contract Inheritance
    • Upgradeable Contracts Should Only Inherit From Other Upgradeable Contracts
    • Do Not Instantiate New Contracts in the Logic Contract
    • Parent Initialization Risks
  • Logic Contract Implementation
    • Avoid Using selfdestruct() or Performing delegatecall()/call() to Untrusted Contracts

32 of 33

Summary

Recap of the workshop 📜

33 of 33

Open floor for questions❓