An Update on the Contract Upgrade Feature

Hi everyone :wave:,

We’re excited to announce that the contract upgrade feature is now fully developed and tested. This feature will allow developers to upgrade their secret contracts without having to create a new contract and have users manually migrating their state. This can be useful for fixing bugs, adding new features, or updating the contract’s security.

The contract upgrade feature saves time and effort for developers, and increases the velocity and flexibility with which developers on Secret Network can build and deploy their contracts. This is because they no longer need to create a new contract and manually migrate user state, which can be a risky and error-prone process. The contract upgrade feature is a valuable tool for developers who want to keep their contracts up-to-date.

To upgrade a contract, the developer will need to specify an admin address when the contract is created. The admin address will be able to initiate the upgrade process by submitting a MsgMigrateContract transaction. The transaction will specify the new contract code ID, and will invoke the migrate() function on the new contract’s code. The new code can optionally perform state migrations inside the migrate() function.

The upgrade process is as follows:

  1. The new contract code is deployed to the network.
  2. A MsgMigrateContract transaction is submitted to the network, specifying the contract address, the new code ID and a message to be sent to the migrate() function on the new code.
  3. The network validates the message and checks that the admin address is authorized to upgrade the contract.
  4. The state of the old contract is migrated to the new contract while keeping the same contract address.

The contract upgrade feature is backward compatible. This means that contracts that were created before the v1.10 upgrade can still be upgraded to the new version. However, the admins of these contracts will need to be hard-coded into the v1.10 upgrade proposal.

We’re currently in the process of collecting a list of contracts that developers want to upgrade. If you have a contract that you want to upgrade, please submit the contract address and the admin address in this form Upgradeable contracts.

We’ll be providing more details about the contract upgrade feature in the coming weeks. In the meantime, please feel free to ask any questions you have in the comments below.

Q&A:

  • Q: What are the security implications of the contract upgrade feature on Secret Network?
  • A: The contract upgrade feature introduces some security risks, as the admin of a contract can upgrade it to have malicious code that can steal funds and private data. This is the same risk that exists on public blockchains, but it is unique to Secret Network in that the malicious code can also steal private data that is stored inside the contract.
    To mitigate these risks, it is important to carefully choose the admin of a contract and to monitor the contract for any suspicious MsgMigrateContract transactions.
    Here are some additional steps that can be taken to mitigate the security risks of the contract upgrade feature:
    • Use a multisig wallet to control the admin keys.
    • Require a super majority vote to approve a contract upgrade (DAOs / multisig).
    • Implement a public code review process for all contract upgrades.
    • Provide a way for users to reproduce the compiled WASM binary from source. This can be done by using the Docker contract optimizer image for compilation and specifying the exact git commit from which the contract was built.
  • Q: What are the benefits of upgrading a contract?
  • A: There are several benefits to upgrading a contract, including:
    • Fixing bugs
    • Adding new features
    • Updating the contract’s security
    • Making the contract compatible with new network features
  • Q: How do I know if my contract needs to be upgraded?
  • A: There are various scenarios where you’d want to upgrade an old contract:
    • Older SNIP-20 tokens that:
      • Don’t support query permits
      • Have the slower permits implementation (before the v1.3 upgrade on May 2022)
      • Don’t record timestamps for transfers
      • Don’t have the recent decoys feature
      • Want to add MetaMask permit support in the future
    • Older SNIP-721 tokens
    • Fixing bugs in highly used contracts
    • Highly used contracts that already have state and that you can’t or don’t want to ask users to manually migrate their state
  • Q: Would the contract code hash change after a contract upgrade?
  • A: Yes, the contract code hash will change after a contract upgrade. This means that any contracts that interacts with the upgraded contract will also need to be updated to use the new code hash. You may also need to update UIs that have the code hash hard-coded.
  • Q: What are the security implications of upgrading a contract?
  • A: There are some security implications to upgrading a contract, such as the risk of introducing new bugs or vulnerabilities. It’s important to carefully review the upgrade process before proceeding. However, you can always perform an upgrade to the old code, provided that the new code didn’t make irreversible state migrations.
  • Q: Can CosmWasm v0.10 contracts be upgraded as well?
  • A: Yes. Any contract can be upgraded to CosmWasm v0.10 or v1.
  • Q: Can a contract be the admin of another contract?
  • A: Yes.
  • Q: Can a contract be the admin of itself?
  • A: Yes.
  • Q: Can a contract be upgraded once and then disable future upgrades?
  • A: For hard-coded admins via governance, only via a future governance proposal . For contracts that were created with an admin, yes , by sending a MsgUpdateAdmin or MsgClearAdmin transaction.

We hope this helps! Please feel free to ask any other questions you have in the comments below.

Onwards and upwards :chart_with_upwards_trend:,

The SCRT Labs Team

11 Likes

Hi all :wave:, I want (or: “have been asked by @ertemann”) to share a few notes about the code hash mechanism.

The code hash mechanism is crucial for input senders to determine which code is permitted to decrypt the input. In 2020, we were confronted with the challenge of preventing replay attacks, where malicious actors could replay an honest user’s input into a malicious contract, potentially exposing the plaintext input. Our solution was to include the code hash of the recipient contract within the encrypted input.

Here’s how it works: the enclave decrypts the input and computes sha256(wasm_bytes). If the code hash within the decrypted input doesn’t match the calculated code hash, the enclave rejects the call with an error. This security measure also applies to contract-to-contract calls, as they are also encrypted.

It’s essential to understand that the enclave cannot directly access a contract’s information from the chain’s storage. This is because such information can be manipulated, as demonstrated by @amiller. As a result, the code hash mechanism remains an implementation detail that we unfortunately couldn’t abstract away for users.

This mechanism can be somewhat inconvenient, especially when dealing with UIs. Additionally, it becomes more complex during contract-to-contract calls, where discovering the other contract’s code hash isn’t always straightforward, leading to convoluted code patterns.

When we announced the hardcoded admins feature as part of the upcoming v1.11 a few weeks ago, @baedrik smartly pointed out a potential issue. If an old contract A has contract B’s code hash stored in its state, it would fail to call B if B undergoes an upgrade. This is because old contracts assumed that pre-v1.11 contracts couldn’t be upgraded, making their code hash immutable.

To address this, we introduced an edge case. All contracts in the hardcoded admins list can also be called with their initial code hash. While this solution resolves the problem, it introduces an attack vector where an old input can be replayed on newer code, even if it was intended to run with the initial code. We’ve decided to accept this as a potential risk for two primary reasons:

  1. We consider contracts on the hardcoded admins list low-risk for such attacks since governance has approved all the admins.
  2. In a future upgrade (ideally v1.12 :crossed_fingers:) we’ll add merkle proofs in the enclave. This will allow the enclave to verify any data stored on the chain’s storage. This mechanism is mainly intended for verification of read_db() operations by contracts, but another key benefit is that transaction inputs will no longer need to include the code hash. Instead, the enclave will query the chain for it. For instance, a user signs a transaction calling contract A, and the enclave can prove that sha256(wasm_bytes) matches the contract’s info stored on-chain.

@baedrik raised another valid point regarding the removal of the code hash requirement in inputs. In the future, contracts may wish to enforce the code hash of the callee contract during contract-to-contract calls. This measure prevents further communication in case the callee has been upgraded, potentially affecting the caller’s behavior unexpectedly. This feature will be added when we remove the requirement to specify the code hash in inputs.

I hope this clarifies things and also provides a glimpse into the future. :blush:

Anyway, back to coding… :ninja:

4 Likes