Skip to content

Commit 82896de

Browse files
authored
[Protocol3] Add OwnedUpgradeabilityProxy from OpenZeppelin (#322)
1 parent f4b9da6 commit 82896de

File tree

4 files changed

+181
-313
lines changed

4 files changed

+181
-313
lines changed

packages/loopring_v3/README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Loopring Protocol (V3) using zkSNARKs
22

33
## About
4+
45
This is a very early version of Loopring's order-based DEX protocol (version 3.0). The code base is still being tested and is not production ready.
56

67
To understand several concepts introduced by the Loopring Protocol, such as order-ring, ring-matching, dual-authoring, free-burning, please read our [whitepaper](https://loopring.org/resources/en_whitepaper.pdf) for Loopring Protocol 2.x.
@@ -34,7 +35,6 @@ To understand the overall design for Loopring 3.0, including Ethereum smart cont
3435
- Can switch to better hash function
3536
- and more...
3637

37-
3838
## Build
3939

4040
`npm run build // first time` or `npm run compile` or `npm run watch`.
@@ -48,12 +48,17 @@ make
4848
```
4949

5050
## Run Unit Tests
51-
* run `npm run ganache` from project's root directory in terminal.
52-
* run `npm run test` from project's root directory in another terminal window.
53-
* run single test: `npm run test -- transpiled/test/xxx.js`
54-
* print info logs in tests: `npm run test -- -i`
55-
* print more detailed debug logs in tests: `npm run test -- -x`
51+
52+
- run `npm run ganache` from project's root directory in terminal.
53+
- run `npm run test` from project's root directory in another terminal window.
54+
- run single test: `npm run test -- transpiled/test/xxx.js`
55+
- print info logs in tests: `npm run test -- -i`
56+
- print more detailed debug logs in tests: `npm run test -- -x`
5657

5758
Running all tests takes around 3 hours on a modern PC with a CPU with 4 cores. Creating proofs is computationaly heavy and takes time even when multi-threading is used. Run individual tests when you can.
5859

5960
Verifier/Prover keys are cached in the `keys` folder. When updating the circuits make sure to delete the keys of older circuit versions because this is not automatically detected.
61+
62+
## Contract Deployment
63+
64+
It's recommended to deploy the protocol with **UpgradeabilityProxy**. For more information, please see https://blog.openzeppelin.com/upgradeability-using-unstructured-storage and https://github.com/OpenZeppelin/openzeppelin-labs/tree/master/upgradeability_using_unstructured_storage.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// This code is taken from https://github.com/OpenZeppelin/openzeppelin-labs
2+
// with minor modifications.
3+
4+
pragma solidity 0.5.10;
5+
6+
import './UpgradeabilityProxy.sol';
7+
8+
/**
9+
* @title OwnedUpgradeabilityProxy
10+
* @dev This contract combines an upgradeability proxy with basic authorization control functionalities
11+
*/
12+
contract OwnedUpgradeabilityProxy is UpgradeabilityProxy {
13+
/**
14+
* @dev Event to show ownership has been transferred
15+
* @param previousOwner representing the address of the previous owner
16+
* @param newOwner representing the address of the new owner
17+
*/
18+
event ProxyOwnershipTransferred(address previousOwner, address newOwner);
19+
20+
// Storage position of the owner of the contract
21+
bytes32 private constant proxyOwnerPosition = keccak256("org.zeppelinos.proxy.owner");
22+
23+
/**
24+
* @dev the constructor sets the original owner of the contract to the sender account.
25+
*/
26+
constructor() public {
27+
setUpgradeabilityOwner(msg.sender);
28+
}
29+
30+
/**
31+
* @dev Throws if called by any account other than the owner.
32+
*/
33+
modifier onlyProxyOwner() {
34+
require(msg.sender == proxyOwner());
35+
_;
36+
}
37+
38+
/**
39+
* @dev Tells the address of the owner
40+
* @return the address of the owner
41+
*/
42+
function proxyOwner() public view returns (address owner) {
43+
bytes32 position = proxyOwnerPosition;
44+
assembly {
45+
owner := sload(position)
46+
}
47+
}
48+
49+
/**
50+
* @dev Sets the address of the owner
51+
*/
52+
function setUpgradeabilityOwner(address newProxyOwner) internal {
53+
bytes32 position = proxyOwnerPosition;
54+
assembly {
55+
sstore(position, newProxyOwner)
56+
}
57+
}
58+
59+
/**
60+
* @dev Allows the current owner to transfer control of the contract to a newOwner.
61+
* @param newOwner The address to transfer ownership to.
62+
*/
63+
function transferProxyOwnership(address newOwner) public onlyProxyOwner {
64+
require(newOwner != address(0));
65+
emit ProxyOwnershipTransferred(proxyOwner(), newOwner);
66+
setUpgradeabilityOwner(newOwner);
67+
}
68+
69+
/**
70+
* @dev Allows the proxy owner to upgrade the current version of the proxy.
71+
* @param implementation representing the address of the new implementation to be set.
72+
*/
73+
function upgradeTo(address implementation) public onlyProxyOwner {
74+
_upgradeTo(implementation);
75+
}
76+
77+
/**
78+
* @dev Allows the proxy owner to upgrade the current version of the proxy and call the new implementation
79+
* to initialize whatever is needed through a low level call.
80+
* @param implementation representing the address of the new implementation to be set.
81+
* @param data represents the msg.data to bet sent in the low level call. This parameter may include the function
82+
* signature of the implementation to be called with the needed payload
83+
*/
84+
function upgradeToAndCall(address implementation, bytes memory data) payable public onlyProxyOwner {
85+
upgradeTo(implementation);
86+
(bool success, ) = address(this).call.value(msg.value)(data);
87+
require(success);
88+
}
89+
}

0 commit comments

Comments
 (0)