SIP-100: Resolver & Cache Improvements

Author
Discussions-Tohttps://research.synthetix.io/
StatusImplemented
Created2020-12-03

Simple Summary

Improve the AddressResolver to improve protocol upgrades, reduce gas of deployments and further decentralization.

Abstract

Reduce the complexity of Synthetix contracts using the AddressResolver in three ways:

  1. Have all contracts that use MixinResolver to be given the immutable ReadProxyAddressResolver and no longer require Owned functionality
  2. Allow all contracts that use MixinResolver to have their caches rebuilt by anyone
  3. Add to the AddressResolver a function to batch and forward requests to build caches of a collection of MixinResolver contracts
  4. Emit events on address import and cache rebuilding
  5. No longer build the list of required addresses a contract needs at runtime in the constructor but rather at compile time where possible.

Motivation

There are currently three main issues necessitating this refactor:

First, the protocolDAO upgrades are cumbersome, having a plethora of cache rebuilding transactions to be invoked individually. Better to batch these where possible.

Second, as ReadProxyAddressResolver is now available and immutable, contracts can rely on it being set at construction and never changed, and ownership can be remove for contracts that only have it for the MixinResolver.

Third, as many contracts also need to work on the OVM, we need to keep contracts down in size. As the OVM transpiler adds extra code around opcodes like SSTORE, we want to reduce the use of them in constructors as much as possible.

Finally, more emitted events help determine issues by leaving a paper trail of actions performed to be easily traced back.

Specification

Overview

  • AddressResolver.importAddresses() to emit an event AddressImported for each address added
  • AddressResolver.rebuildCaches() is exposed (and non-protected), for ease-of use
  • MixinResolver no longer requires Owned as the resolver property is set once only on construction (with the expectation that ReadProxyAddressResolver will be used.
  • MixinResolver has a predicate view isResolverCached()
  • MixinResolver has a rebuildCache() function (publicly available) for the contract to rebuild its cache. This function also emits a CacheUpdated event for each item added to its private cache
  • MixinResolver.requireAndGetAddress() uses abi.encodePacked for string concatenation and a simpler API.
  • MixinResolver no longer performs tasks in the constructor. Contracts using the mixin must implement the abstract resolverAddressesRequired function.

Rationale

This approach mimics the same functionality as currently on-chain, and does not add any more gas to Synthetix user transactions.

Technical Specification

contract AddressResolver {

    // restricted function
    function importAddresses(bytes32[] calldata names, address[] calldata destinations) external // ... emits AddressImported

    // public function
    function rebuildCaches(MixinResolver[] calldata destinations) external // ... invokes MixinResolver.rebuildCache()

    // event
    event AddressImported(bytes32 name, address destination);
}
contract MixinResolver {

    // public function
    function rebuildCache() external // ... emits CacheUpdated

    // abstract view
    function resolverAddressesRequired() public view returns (bytes32[] memory addresses);

    // view
    function isResolverCached() external view returns (bool) // ...

    // event
    event CacheUpdated(bytes32 name, address destination);
}

Test Cases

See PR#904

Configurable Values (Via SCCP)

N/A