Skip to content

Latest commit

 

History

History
89 lines (66 loc) · 3.42 KB

rfc-4-secure-contract-upgrades.adoc

File metadata and controls

89 lines (66 loc) · 3.42 KB

RFC 4: Secure upgrades for contracts operating staked balances

SUPERSEDED
Important
This RFC has been superseded by an alternative described in RFCs 9 and 11. It was never implemented as described.

1. Background

Following best practices for ERC-20 Tokens, we have non-upgradable and non-ownable Token and Token staking contracts, which means there is no backdoor to modify the contract storage or change the implementation. Amongst other things, these contracts only allow token transfers to be executed by the token holders. Since token staking functionality might need upgrading, it was decided to simply issue and deploy a new contract and advise stakers to migrate their balances to it.

A different upgrade approach taken from Open Zeppelin was implemented for the rest of the contracts; this RFC states the pitfalls of the approach and proposes alternative way similar to what we already have for Token staking contracts.

1.1. Current Functionality

Current upgrading functionality influenced by Open Zeppelin libraries makes upgradable contract address and storage persistent and the logic can be upgraded by the contract owner. They do so by updating the implementation address in the persistent proxy contract. The method is also known as "Eternal Storage". This was considered a good approach for all the forthcoming Keep contracts including Group selection and Random beacon. A concern has been raised during implementation of stake slashing functionality where an upgradable contract such as Group Contract has to be authorized to modify stake balances. Since the address and storage are persistent in case of a compromised implementation all staked balances are at risk. Imagine a deploy key that is used to update the implementation is stolen, the hacker has full access to the contract storage immediately by updating contract with his implementation. Besides if the contract address was authorized to move stakers balances those will be lost as well.

1.2. Goal

Minimize the risk of lost/stolen staked tokens in the case of a hacked or bad implementation upgrade of the contracts that require full access to modify balance of a staker.

1.3. Implementation

Each new contract that does "slashing/reward" changes on staked token balances must be a non-upgradable and non-ownable one to minimize attack surface. Functionality upgrades are only possible by deploying a new implementation as a new contract. The address of this contract must be re-authorized by a staker. Stakers do so by calling the authorize(address) method on a staking contract. A client should only authorize official contract addresses from the metacontract list maintained by Keep organization along with the confirmation by two or more Keybase-proven channels.

The contracts with authorize() method should also include a "panic button" - a method that cancels all authorizations in case of emergency. This should be restricted to be called by a Keep organization account used to deploy this contract.

1.4. Limitations

Not particularly a limitation but a move from being able to do a seamless and instant upgrade to a drawn-out one where stakers have to reauthorize a newly deployed version.

1.5. Proof of Concept

The basis for the concept can be seen in the current Staking contracts and TokenStaking.sol