Skip to content
This repository has been archived by the owner on Jan 18, 2023. It is now read-only.

Commit

Permalink
Time Lock Upgradability (#288)
Browse files Browse the repository at this point in the history
* First steps

* Implemented timeLock

* Add param to Core

* Complete coreTimeLock upgrade specs

* Add timelock modifiers

* Update compile error

* Add core internal to mock

* Remove from internal

* Finish rebase

* Add timelock upgrade to module

* Move TimeLock to its own library and state
  • Loading branch information
felix2feng committed Nov 19, 2018
1 parent 15af3fd commit 87c594c
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 3 deletions.
9 changes: 8 additions & 1 deletion contracts/core/extensions/CoreInternal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pragma solidity 0.4.25;
import { Ownable } from "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import { CoreState } from "../lib/CoreState.sol";
import { AddressArrayUtils } from "../../lib/AddressArrayUtils.sol";
import { TimeLockUpgrade } from "../../lib/TimeLockUpgrade.sol";


/**
Expand All @@ -30,7 +31,8 @@ import { AddressArrayUtils } from "../../lib/AddressArrayUtils.sol";
*/
contract CoreInternal is
Ownable,
CoreState
CoreState,
TimeLockUpgrade
{
using AddressArrayUtils for address[];

Expand All @@ -47,6 +49,7 @@ contract CoreInternal is
)
external
onlyOwner
timeLockUpgrade
{
state.validFactories[_factory] = true;
}
Expand Down Expand Up @@ -79,6 +82,7 @@ contract CoreInternal is
)
external
onlyOwner
timeLockUpgrade
{
state.exchanges[_exchangeId] = _exchange;
}
Expand Down Expand Up @@ -109,6 +113,7 @@ contract CoreInternal is
)
external
onlyOwner
timeLockUpgrade
{
state.validModules[_module] = true;
}
Expand Down Expand Up @@ -181,6 +186,7 @@ contract CoreInternal is
)
external
onlyOwner
timeLockUpgrade
{
state.validPriceLibraries[_priceLibrary] = true;
}
Expand Down Expand Up @@ -240,6 +246,7 @@ contract CoreInternal is
)
external
onlyOwner
timeLockUpgrade
{
state.signatureValidator = _signatureValidator;
}
Expand Down
5 changes: 4 additions & 1 deletion contracts/lib/Authorizable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pragma solidity 0.4.25;
import { Ownable } from "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import { SafeMath } from "openzeppelin-solidity/contracts/math/SafeMath.sol";
import { AddressArrayUtils } from "./AddressArrayUtils.sol";
import { TimeLockUpgrade } from "./TimeLockUpgrade.sol";


/**
Expand All @@ -29,7 +30,8 @@ import { AddressArrayUtils } from "./AddressArrayUtils.sol";
* through the onlyAuthorized modifier. Permissions can be managed only by the Owner of the contract.
*/
contract Authorizable is
Ownable
Ownable,
TimeLockUpgrade
{
using SafeMath for uint256;
using AddressArrayUtils for address[];
Expand Down Expand Up @@ -78,6 +80,7 @@ contract Authorizable is
function addAuthorizedAddress(address _authTarget)
external
onlyOwner
timeLockUpgrade
{
// Require that address is not already authorized
require(
Expand Down
112 changes: 112 additions & 0 deletions contracts/lib/TimeLockUpgrade.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
Copyright 2018 Set Labs Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

pragma solidity 0.4.25;

import { Ownable } from "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import { SafeMath } from "openzeppelin-solidity/contracts/math/SafeMath.sol";


/**
* @title TimeLock Upgrade
* @author Set Protocol
*
* The TimeLockUpgrade contract contains a modifier for handling minimum time period updates
*/
contract TimeLockUpgrade is
Ownable
{
using SafeMath for uint256;

/* ============ State Variables ============ */

// Timelock Upgrade Period in seconds
uint256 public timeLockPeriod;

// Mapping of upgradable units and initialized timelock
mapping(bytes32 => uint256) public timeLockedUpgrades;

/* ============ Events ============ */

event UpgradeRegistered(
bytes32 _upgradeHash,
uint256 _timestamp
);

/* ============ Modifiers ============ */

modifier timeLockUpgrade() {
// If the time lock period is 0, then allow non-timebound upgrades.
// This is useful for initialization of the protocol and for testing.
if (timeLockPeriod == 0) {
_;

return;
}

// The upgrade hash is defined by the hash of the transaction call data,
// which uniquely identifies the function as well as the passed in arguments.
bytes32 upgradeHash = keccak256(
abi.encodePacked(
msg.data
)
);

uint256 registrationTime = timeLockedUpgrades[upgradeHash];

// If the upgrade hasn't been registered, register with the current time.
if (registrationTime == 0) {
timeLockedUpgrades[upgradeHash] = block.timestamp;

emit UpgradeRegistered(
upgradeHash,
block.timestamp
);

return;
}

require(
block.timestamp >= registrationTime.add(timeLockPeriod),
"TimeLockUpgrade.timeLockUpgrade: Upgrade requires time lock period to have elapsed."
);

// Reset the timestamp to 0
timeLockedUpgrades[upgradeHash] = 0;

// Run the rest of the upgrades
_;
}

/* ============ Function ============ */

/**
* Change timeLockPeriod period. Generally called after initially settings have been set up.
*
* @param _timeLockPeriod Time in seconds that upgrades need to be evaluated before execution
*/
function setTimeLockPeriod(
uint256 _timeLockPeriod
)
external
onlyOwner
{
// Only allow setting of the timeLockPeriod the first time
if (timeLockPeriod == 0) {
timeLockPeriod = _timeLockPeriod;
}
}
}
21 changes: 21 additions & 0 deletions contracts/mocks/lib/TimeLockUpgradeMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
pragma solidity 0.4.25;
pragma experimental "ABIEncoderV2";

import { TimeLockUpgrade } from "../../lib/TimeLockUpgrade.sol";

// Mock contract implementation of TimeLockUpgrade functions
contract TimeLockUpgradeMock is
TimeLockUpgrade
{
uint256 public testUint;

function testTimeLockUpgrade(
uint256 _testUint
)
public
timeLockUpgrade
{
testUint = _testUint;
}
}

Loading

0 comments on commit 87c594c

Please sign in to comment.