-
Notifications
You must be signed in to change notification settings - Fork 1
/
BaseController.sol
87 lines (72 loc) · 3.74 KB
/
BaseController.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.17;
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
import {OVAL} from "../Oval.sol";
/**
* @title BaseController providing the simplest possible controller logic to govern who can unlock the OVAL.
* @dev Custom Controllers can be created to provide more granular control over who can unlock the OVAL.
*/
abstract contract BaseController is Ownable, OVAL {
// these don't need to be public since they can be accessed via the accessor functions below.
uint256 private lockWindow_ = 60; // The lockWindow in seconds.
uint256 private maxTraversal_ = 10; // The maximum number of rounds to traverse when looking for historical data.
mapping(address => bool) public unlockers;
/**
* @notice Enables the owner to set the unlocker status of an address. Once set, the address can unlock the OVAL
* and by calling unlockLatestValue as part of an MEV-share auction.
* @param unlocker The address to set the unlocker status of.
* @param allowed The unlocker status to set.
*/
function setUnlocker(address unlocker, bool allowed) public onlyOwner {
unlockers[unlocker] = allowed;
emit UnlockerSet(unlocker, allowed);
}
/**
* @notice Returns true if the caller is allowed to unlock the OVAL.
* @dev This implementation simply checks if the caller is in the unlockers mapping. Custom Controllers can override
* this function to provide more granular control over who can unlock the OVAL.
* @param caller The address to check.
* @param _lastUnlockTime The timestamp of the latest unlock to the OVAL. Might be useful in verification.
*/
function canUnlock(address caller, uint256 _lastUnlockTime) public view override returns (bool) {
return unlockers[caller];
}
/**
* @notice Enables the owner to set the lockWindow.
* @dev If changing the lockWindow would cause OVAL to return different data the permissioned actor must first
* call unlockLatestValue through flashbots via eth_sendPrivateTransaction.
* @param newLockWindow The lockWindow to set.
*/
function setLockWindow(uint256 newLockWindow) public onlyOwner {
(int256 currentAnswer, uint256 currentTimestamp) = internalLatestData();
lockWindow_ = newLockWindow;
// Compare OVAL results so that change in lock window does not change returned data.
(int256 newAnswer, uint256 newTimestamp) = internalLatestData();
require(currentAnswer == newAnswer && currentTimestamp == newTimestamp, "Must unlock first");
emit LockWindowSet(newLockWindow);
}
/**
* @notice Enables the owner to set the maxTraversal.
* @param newMaxTraversal The maxTraversal to set.
*/
function setMaxTraversal(uint256 newMaxTraversal) public onlyOwner {
maxTraversal_ = newMaxTraversal;
emit MaxTraversalSet(newMaxTraversal);
}
/**
* @notice Time window that bounds how long the permissioned actor has to call the unlockLatestValue function after
* a new source update is posted. If the permissioned actor does not call unlockLatestValue within this window of a
* new source price, the latest value will be made available to everyone without going through an MEV-Share auction.
* @return lockWindow time in seconds.
*/
function lockWindow() public view override returns (uint256) {
return lockWindow_;
}
/**
* @notice Max number of historical source updates to traverse when looking for a historic value in the past.
* @return maxTraversal max number of historical source updates to traverse.
*/
function maxTraversal() public view override returns (uint256) {
return maxTraversal_;
}
}