Documentation for upgradeability contracts (#332)
This commit is contained in:
parent
3b4220ee44
commit
0241a264bb
|
@ -2,6 +2,13 @@ pragma solidity 0.4.24;
|
|||
|
||||
import "./EternalStorageProxy.sol";
|
||||
|
||||
/**
|
||||
* @title ClassicEternalStorageProxy
|
||||
* @dev This proxy holds the storage of the token contract and delegates every call to the current implementation set.
|
||||
* Besides, it allows to upgrade the token's behaviour towards further implementations, and provides basic
|
||||
* authorization control functionalities.
|
||||
* The only differency between this contract and EternalStorageProxy is a provided support of pre-Byzantium environment.
|
||||
*/
|
||||
contract ClassicEternalStorageProxy is EternalStorageProxy {
|
||||
// solhint-disable-next-line no-complex-fallback
|
||||
function() public payable {
|
||||
|
@ -11,6 +18,10 @@ contract ClassicEternalStorageProxy is EternalStorageProxy {
|
|||
assembly {
|
||||
let ptr := mload(0x40)
|
||||
calldatacopy(ptr, 0, calldatasize)
|
||||
/*
|
||||
instead of reading `returndatasize` and `returdatacopy` later,
|
||||
this stores the returned data directly into the memory
|
||||
*/
|
||||
let result := delegatecall(gas, _impl, ptr, calldatasize, 0, len)
|
||||
|
||||
switch result
|
||||
|
@ -23,6 +34,11 @@ contract ClassicEternalStorageProxy is EternalStorageProxy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Tells the called function return data size
|
||||
* @param sig representing the signature of a called function
|
||||
* @return size of return data in bytes
|
||||
*/
|
||||
function getSize(bytes4 sig) public view returns (uint256) {
|
||||
uint256 ret = uintStorage[keccak256(abi.encodePacked("dataSizes", sig))];
|
||||
if (ret == 0) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# Upgradeability contracts
|
||||
|
||||
This directory contains contracts needed for the idea of upgradeable contracts. The source code for this contracts was originally taken from [openzeppelin-labs](https://github.com/OpenZeppelin/openzeppelin-labs/tree/8212ac638ce0a6517fd1c4c7f445fe9665925020/upgradeability_using_eternal_storage) repository.
|
||||
|
||||
Since the original code is not recommended for production use, it is not directly imported into this project.
|
||||
|
||||
During the development process and performing security audits, the following minor changes were introduced:
|
||||
- Required solidity compiler version was fixed at `0.4.24`, since this version is used in the source code of other contracts. Deprecated syntax for constructors and emitting events was also updated to a new one.
|
||||
- Access modifier `onlyProxyOwner` was renamed to `onlyUpgradeabilityOwner`. Function calls to `proxyOwner()` in `OwnedUpgradeabilityProxy.sol` were directly replaced by calls to `upgradeabilityOwner()`, in order to avoid possible ambiguity. See [#195](https://github.com/poanetwork/tokenbridge-contracts/issues/195).
|
||||
- Functions modifier `public` was replaced by `external` where possible.
|
||||
- Version field type was changed from `string` to `uint256`, as it reduces possible complexity and allows to easily introduce a version mutability requirement (`require(version > _version);` in `UpgradeabilityProxy.sol`).
|
||||
- Additional assembly operation was introduced in `Proxy.sol`, opcodes in line `mstore(0x40, add(ptr, returndatasize))` guarantee the correct value of free memory pointer for execution of next instructions.
|
||||
- Additional check in `UpgradeabilityProxy.sol` was added, `require(AddressUtils.isContract(implementation))` verifies that new implementation is not a regular address, but a contract. See [#256](https://github.com/poanetwork/tokenbridge-contracts/pull/256).
|
||||
- Contract `ClassicEternalStorageProxy.sol` was added for the use in pre-Byzantium Ethereum Classic network, which does not support [EIP-211](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-211.md). See this comment in [#161](https://github.com/poanetwork/tokenbridge-contracts/pull/161#issuecomment-473888305).
|
|
@ -23,8 +23,14 @@ contract UpgradeabilityProxy is Proxy, UpgradeabilityStorage {
|
|||
*/
|
||||
function _upgradeTo(uint256 version, address implementation) internal {
|
||||
require(_implementation != implementation);
|
||||
|
||||
// This additional check verifies that provided implementation is at least a contract
|
||||
require(AddressUtils.isContract(implementation));
|
||||
|
||||
// This additional check guarantees that new version will be at least greater than the privios one,
|
||||
// so it is impossible to reuse old versions, or use the last version twice
|
||||
require(version > _version);
|
||||
|
||||
_version = version;
|
||||
_implementation = implementation;
|
||||
emit Upgraded(version, implementation);
|
||||
|
|
Loading…
Reference in New Issue