EIPs/EIPS/eip-3561.md

92 lines
6.7 KiB
Markdown
Raw Normal View History

---
eip: 3561
title: Trust Minimized Upgradeability Proxy
author: Sam Porter (@SamPorter1984)
discussions-to: https://ethereum-magicians.org/t/trust-minimized-proxy/5742
status: Draft
type: Standards Track
category: ERC
created: 2021-05-09
---
## Simple Summary
Additional storage slots for upgradeability proxy to decrease trust in interaction with upgradeable smart contracts.
## Abstract
Removing trust from upgradeability proxy is required for anonymous developers. To achieve that, disallowing sudden, potentially malicious upgrades is required. This EIP introduces a time lock, a period of one month, before defined by proxy admin implementation becomes active implementation.
## Motivation
It's usually not possible for anonymous developers who use upgradeability proxies to gain community trust.
Fairer, better future for humanity absolutely requires some developers to stay anonymous while still attract vital attention to solutions they propose and at the same time leverage the benefits of possible upgradeability. For example, a project like Collateralized Asset Protocol allows to trade stocks and securities on the blockchain in a purely decentralized way making the developers of such projects potentially risking their freedom. Aletheo was born to fight tyranny.
Extinction is more likely with closed internet borders. As long as internet has eyes everywhere, devastating conventional warfare is less likely to happen regardless of power vacuum or exponential increase in existential threats.
## Specification
The specification is an addition to the standard [EIP-1967](./eip-1967.md) transparent proxy design.
The specification focuses on the slots it adds. All admin interactions with trust minimized proxy must emit an event to make admin actions trackable, and all admin actions must be guarded with `onlyAdmin()` modifier.
### Next Logic Contract Address
Storage slot `0xe8c186b11a4be12af079b0a5c235146db6f3615b2a8b1b47f9bfe3a956337ef9` (obtained as `bytes32(uint256(keccak256('eip3561.proxy.next_implementation')) - 1)`).
Logic address must be first defined as next logic, before it can function as actual logic implementation stored in EIP-1967 `IMPLEMENTATION_SLOT`.
Admin interactions with next logic contract address correspond with these methods and events:
```solidity
// sets next logic contract address and initializes it. Emits NextLogicDefined
// 0x as calldata is an equivalent of proposeTo()
function proposeToAndCall(address implementation, bytes calldata data) external onlyAdmin;
// sets the address stored as next implementation as current IMPLEMENTATION_SLOT
// as soon UPGRADE_BLOCK_SLOT allows
function upgrade() external onlyAdmin;
// cancelling is possible for as long as upgrade() for given next logic was not called
// emits NextLogicCanceled
function cancelUpgrade() external onlyAdmin;
event NextLogicDefined(address indexed nextLogic, uint earliestArrivalBlock); // important to have
event NextLogicCanceled(address indexed oldLogic);
```
### Upgrade Block
Storage slot `0xd366e20ef9f21888e3d225d6a18f0bceb0ce0008a1e881be9a0467a0293afc96` (obtained as `bytes32(uint256(keccak256('eip3561.proxy.upgrade_block')) - 1)`).
On/after this block next logic contract address can be set to EIP-1967 `IMPLEMENTATION_SLOT` or, in other words, start to function as current logic. Updated automatically and is shown as `earliestArrivalBlock` in the event `NextLogicDefined`.
### Propose Block
Storage slot `0x1e166c9744902ecbb9f589bbc9e7da5f078e553ad162c2ee62c71827916db75f` (obtained as `bytes32(uint256(keccak256('eip3561.proxy.propose_block')) - 1)`).
Defines after/on which block *proposing* next logic is possible. Required for convenience, for example can be manually set to a year from given time, so that the users can have peace of mind during the year. Can be set to maximum number to completely seal the code, must not overflow.
Admin interactions with this slot correspond with this method and event:
```solidity
function prolongLock(uint n) external onlyAdmin;
event UpgradesRestrictedUntil(uint block);
```
### Deadline Block
Storage slot `0x560a0645803da084600e483b1076fd54059fdee9045033b88b51d342faf2b2af` (obtained as `bytes32(uint256(keccak256('eip3561.proxy.deadline')) - 1)`).
Defines after/on which block it becomes impossible to upgrade the contract, can be set in constructor if used or can be set many times as long as next value is lower than previous. Required in case of probability that the project development can be compromised, unlike `PROPOSE_BLOCK_SLOT`, deadline is less likely to require any urgent transaction like `PROPOSE_BLOCK_SLOT`.
Admin interactions with this slot should correspond with this method and event:
```solidity
function setDeadline(uint block) external onlyAdmin;
event DeadlineSet(uint block);
```
### Trust_minimized Boolean
Storage slot `0x17dc395ab915c140774b2c05da17fd5b71a2d193e53bc9732d6b62d419a46635` (obtained as `bytes32(uint256(keccak256('eip3561.proxy.trust_minimized')) - 1)`).
False by default and can only ever be set true. While it is false, then the proxy operates exactly as standard EIP-1967 transparent proxy, which allows to correct potential mistakes of first deployment. After set to true, all above specification becomes active.
Admin interactions with this slot should correspond with this method and event:
```solidity
function removeTrust() external onlyAdmin;
event TrustRemoved();
```
## Rationale
An argument "just don't make such contracts upgadeable at all" fails when it comes to complex systems. It might be impossible to model complex systems right on first try.
A proxy is easily abusable by anonymous soulless scammers without a time delay before an actual upgrade(change of current implementation address) goes live. A time delay is probably unavoidable, even if it means that inexperienced developers might not have confidence using it. Albeit this is a downside of this EIP, it's a critically important option to have in smart contract development today.
Propose block adds to convenience if used, so should be kept. An ability to cancel next logic can also be important for the same reason. Deadline block, while can be omitted, can be critically important for some projects, it would be reasonable to rather keep it too. Unless developers always write correct automatic deployment scripts, trustless boolean is required from my own experience, because I once failed to execute 15 deployment steps correctly.
## Implementation
The following implementation is an example which lacks trustless boolean slot and uses `NEXT_LOGIC_BLOCK_SLOT` instead of `UPGRADE_BLOCK_SLOT` to get farther slot value: [Aletheo repository](https://github.com/SamPorter1984/Aletheo/blob/main/contracts/TrustMinimizedProxy.sol).
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).