Skip to content

ERC: Proxy standard #121

Closed
Closed
@SilentCicero

Description

ERC
Title: Proxy standard
Status: Draft
Type: Informational
Created: 22.06.2016
Resolution: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs

Abstract

The following describes standard functions a proxy contract can implement.

Motivation

Many Ethereum users and smart-contracts hold and manage digital assets. A unified way to hold, acquire and transfer digital assets could greatly simplify and unify the designs of many contractual services making them more inter-operable with each other, while also gaining from the design benefits of standardization. Many contractual services also require a single persistent account at which to transact within the ecosystem. These services could also greatly benefit from a single unified contractual design enabling this practice to happen in a predictable and consistent way.

Rational

This allows Ethereum users/services to store, transfer and manage multiple kinds of digital assets in a single simple vetted standardized smart-contract. By doing so, we simplify digital asset acquisition, storage and management. A proxy standard also simplifies and/or unified contractual design of governance, identity or financial services on Ethereum. While there is always the potential that the implementer contract of a Proxy could be compromised or poorly design and all assets exposed to attack or freezing, we can expect at the very least the proxy contract implementer to be able to transfer its proxy's ownership (and the digital assets contained therein).

Specification

  1. A single contract with two methods (i.e. transfer_implementer, and forward_transaction) and one variable (i.e. implementer).
  2. The transfer_implementer method is solely responsible for changing ownership from the stored implementer to a new implementer and is access restricted to the implementer and the contract itself.
  3. The forwarding method forward_transaction has three inputs: address _destination, uint _value, bytes _bytecode.
  4. The forward_transaction method is access restricted to the implementer only.
  5. The forward_transaction forwards transactions to the destination address as the ProxyContract address.
  6. The StandardProxy contract implements the Proxy interface contract containing the forward_transaction and transfer_ownership methods.

Code for Proxy contract interface

contract Proxy {
    function forward_transaction (address _destination, uint _value, bytes _bytecode) {}
    function transfer_implementer (address _implementer) {}
}

Code for the StandardProxy contract

import "Proxy.sol";

contract StandardProxy is Proxy {

    function forward_transaction (address _destination, uint _value, bytes _bytecode) {
        if(msg.sender == implementer) {
            if(!_destination.call.value(_value)(_bytecode)) {
                throw;
            }
        }
    }

    function transfer_implementer (address _implementer) {
        if(msg.sender == implementer || msg.sender == address(this)) {
            implementer = _implementer;
        }
    }

    address implementer;
}

StandardProxy contract in use with a factory contract

import "StandardProxy.sol";

contract ImplementedStandardProxy is StandardProxy {
    function ImplementedStandardProxy(address _implementer) {
        implementer = _implementer;
    }

    function getImplementer() constant returns (address) {
       return implementer;
    }
}

contract ImplementedStandardProxyFactory {
    function createStandardProxy(address _implementer) returns (address standardProxyAddress) {
        standardProxyAddress = new ImplementedStandardProxy(_implementer);
    }
}

Potential Attack Vectors/Pitfalls

  • rare use of self access restriction: this is a very uncommon use of contract access restriction and is potentially vulnerable because of this fact (just an odd use of access restriction).
  • re-entry: outward call contract re-entry is a worry in the forward_transaction method.
  • compromised implementer contract/user account: if the implementer contract is compromised by an attacker all digital assets held by the proxy are potentially exposed to attack and theft. The proxy is not suppose to solve this. It is merely suppose to provide a contractual base on which to bond digital assets too.
  • poorly designed implementer contracts: an implementer contract may end up being poorly design or broken, potentially locking the digital assets in the proxy forever. If a contract supports the use of proxy contracts we can then as contract architects expect them to, at the very least, be able to transfer ownership of the proxy. Thus simplifying our base expectations and concerns for contracts that manage digital assets.
  • transaction forwarding/routing costs: if implementer systems use a proxy to manage digital assets and to represent an identity of that system, there is the additional cost incurred by forwarding transactions through the abstracted implementer, into the proxy and out into the ecosystem. This adds additional gas costs that need to be considered.
  • empty/invalid bytecode inputs: there may be potential issues with forwarding transactions that have no bytecode (I cant think of any, but it does seem like it could present issues in the future -- this is merely my intuition here, nothing else).

Examples of proxy contract designs

Notes

  • re-entry must be addressed in the forward_transaction method.
  • proxies should be kept, simple, robust, reusable and stupid (they are meant to be used by other contract interfaces)
  • use the "owner" contract instead of "implementer" term/concept (in defense of the implementer term/concept: "ownership" is certainly a valid term/concept here, however, implementer does seem more metaphysically accurate, as the term "owner" only implies ownership, where as implementer implies that which can implement state change within and as the contract -- this is to be debated however and perhaps it just has too much overlap with the "owner" contract infrastructure).
  • perhaps "proxy" is not the right term here, the dappsys ecosystem uses the term "BaseActor", which also seems appropriate and accurate. However, in conversation and in deep mediation, I believe "proxy" to be a better descriptive term here.
  • proxy contracts (1) simplify, unify and standardize digital asset acquisition and management while also providing (2) a persistent account identity at which services and users can transact with the ecosystem, although I do believe there to be more benefits
  • proxy contracts also help us manage expectations of contracts that hold digital assets or need a persistent account within the ecosystem

A special thanks and credit goes to Christian Lundkvist, Nikolai Mushegian, Simon de la Rouviere, Niran Babalola, and Peter Borah for furthering the design of proxy and proxy like smart-contracts on Ethereum.

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions