SIP-173: Synth Upgrader Contract


Simple Summary

Create and deploy a SynthUpgrader contract allowing the protocolDAO to easily upgrade the underlying Synth.sol logic contract in a single atomic transaction.


Following the success of contract-based migrations in SIP-151, this SIP proposes a SynthUpgrader migration contract to more easily handle the various aspects of a synth's logic upgrade and to avoid system downtime. This includes removing the old synth, adding the new one, updating its token state and proxy, along with the address resolver. This SIP also proposes supporting migration in batches, rather than a single synth at a time, to more easily complete the process.


There are a number of reasons to replace a synth's logic contract outside of a regular deploy. The most common is when a synth is marked for delisting and requires purging, but the synth is not purgeable. This is relevant in the case of both SIP-166 and SIP-169 as the long synths mentioned in both SIPs are not marked as purgeable. Currently there exists a command to do this in the synthetix repo - requiring at least 6 protocolDAO transactions per synth. Moreover, because the transactions are not atomic[1], the system currently needs suspension to perform the replacements, which cause disruption to regular users and exchanges.

This SIP proposes leveraging the work begun with migration contracts in SIP-151 by creating a reusable and permissioned SynthUpgrader contract.

  1. To replace a synth, the totalSupply needs to be set to 0 in order for it to be removed from the sytem however the new synth needs to track the same totalSupply. If we don't upgrade synths atomically, any issuing or burning of a synth's supply (via an exchange) that happens in between fetching and persisting the totalySupply can lead to data corruption - hence why in the past we've opted to suspend the system.



The creation of a custom and reusable SynthUpgrader contract that allows the batch upgrades of synths.


Unlike SIP-151, the logic of upgrading a synth is consistent and fairly intricate (requiring custom code and predicates that the generate-solidity command isn't able to reproduce). Thus, it makes sense to deploy a reusable SynthUpgrader contract which requires the new Synth contract be predeployed and only allow execution from the protocolDAO.

Technical Specification

interface ISynthUpgrader {
    // Restricted to owner
    function upgrade(bytes32[] calldata synthContractLabels, address[] calldata newSynths) external;

Test Cases

  • When upgrade is invoked by a non-owner, Then the transaction reverts
  • When upgrade is invoked by the owner with a label that doesn't exist, Then the transaction reverts
  • When upgrade is invoked by the owner with a label for a contract that isn't a synth, Then the transaction reverts
  • When upgrade is invoked by the owner with a synth that has a different currency key, token state or proxy to the existing synth, Then the transaction reverts
  • When upgrade is invoked by the owner otherwise, Then it replaces all synths given

Configurable Values (Via SCCP)


Copyright and related rights waived via CC0.