upgradeable-proxy-plus
Version:
Extends https://github.com/CCEG-Blockchain-UN-Lab/upgradeable-proxy with Ownable super contract and utilizing safe policies for the upgrade mechanism.
117 lines (99 loc) • 4.68 kB
Markdown
# Upgradeable Proxy Plus
Based on upgradeable-proxy. More info [here](https://github.com/CCEG-Blockchain-UN-Lab/upgradeable-proxy).
## Features
- Implements both upgradeable-proxy features at same time:
- Upgrade safety and protection
- Experimental safety features[*](#note) were implemented to the upgradeable pattern to protect the contract from being accidentally or maliciousl upgraded to the wrong contract. A target contract for the SafeProxy must satisfy, at a minimum, the following conditions to be able to call Proxy.upgradeTo() to change the target:
1. Must have a address target variable
2. Must have a upgradeTo(address) public function
3. Must have a transferOwnership(address) public function
- Permissioned (Ownable) proxy upgrade
- Ownable to allow the administrator of the proxy to be set as a multisig or DAO-like contract to provide distributed governance.
- Inherits from upgradeable-proxy
- 100% Upgradeable strategy
- Comprehensive test suite
### Note:
- empty functions that do nothing will satisfy these conditions.
- one of the safety features depends on the use of the EXTCODESIZE opcode which may not work after the Serenity hard fork.
- carefully consider if these safety features are necessary, onced deployed they cannot be changed.
## Instalation
```bash
npm install upgradeable-proxy-plus
```
## Usage
### Deploy Upgradeable CheckContract
Deploy Upgradeable CheckContract so that after Serenity hardfork, the method to check if an address is a contract can be upgraded. More information [here](https://github.com/CCEG-Blockchain-UN-Lab/upgradeable-proxy/blob/master/contracts/CheckContract.sol#L13)
```javascript
let checkContractInstance = await deployer.deploy(CheckContract);
```
### Deploy CheckContract's Proxy.
Deploy a Proxy for the just deployed CheckContract.
```javascript
let proxyInstance = await deployer.deploy(
Proxy,
checkContractInstance.address
);
```
### Get CheckContract's instance by proxy
Get the instance of the CheckContract by proxy, and initialize.
```javascript
let checkContractInstanceByProxy = CheckContract.at(proxyInstance.address);
await checkContractInstanceByProxy.initialize();
```
### Make some tests
(OPTIONAL) Make some tests to make sure the method isContract called by proxy is properly working.
```javascript
let testOne = await checkContractInstanceByProxy.isContract.call(
checkContractInstanceByProxy.address
);
assert.equal(testOne, true);
let testTwo = await checkContractInstanceByProxy.isContract.call(
"0x627306090abab3a6e1400e9345bc60c78a8bef57"
);
assert.equal(testTwo, false);
```
### Deploy the UpgradeablePlus contract
```javascript
let addressSimpleV1 = await deployer.deploy(AddressSimpleV1);
```
### Deploy AddressSimpleV1's ProxyPlus
Deploy a ProxyPlus for the just deployed AddressSimpleV1Safe.
```javascript
let proxyPlus = await ProxyPlus.new(
addressSimpleV1.address,
checkContractInstanceByProxy.address
);
```
### Get AddressSimpleV1's instance by proxy
Get the instance of the AddressSimpleV1Safe by proxy, and initialize.
```javascript
let addressSimpleV1byProxy = AddressSimpleV1.at(proxyPlus.address);
await addressSimpleV1byProxy.initialize();
```
### Make some tests
(OPTIONAL) Make some tests to make sure the UpgradeablePlus contract called by proxy is properly working.
```javascript
const inputValue = "0xa4532e9f6f9c4e4abb89bdbb73d3003210ede61c",
inputValue2 = "0x5c28D962c93282C6Fbe820f9AB33844D96b4853e";
await addressSimpleV1byProxy.setValue(inputValue);
let value = await addressSimpleV1byProxy.getValue.call();
assert.equal(value, inputValue, "Not equal to inputValue");
let addressSimpleV2 = await deployer.deploy(AddressSimpleV2);
await addressSimpleV1byProxy.upgradeTo(addressSimpleV2.address);
await addressSimpleV1byProxy.initialize();
value = await addressSimpleV1byProxy.getValue.call();
assert.equal(value, inputValue, "Not equal to inputValue");
await addressSimpleV1byProxy.setValue(inputValue2);
value = await addressSimpleV1byProxy.getValue.call();
assert.equal(
value,
"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98",
"Not equal to constant defined in function"
);
```
The full example was written inside migrations and is fully functional [here](https://github.com/CCEG-Blockchain-UN-Lab/upgradeable-proxy-plus/blob/master/migrations/2_deploy_contracts.js).
### How to import these library contracts?
Use the following strategy to import library contracts to your own contracts
```javascript
import "upgradeable-proxy-plus/contracts/UpgradeablePlus.sol";
```