Skip to content

Commit

Permalink
Merge pull request #103 from smart-transaction/feat/access-control-in…
Browse files Browse the repository at this point in the history
…-scheduler

Added access control to block clock scheduler
  • Loading branch information
mevtxn authored Dec 20, 2024
2 parents 5632c74 + 4a6dc55 commit 9d0d138
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 44 deletions.
9 changes: 4 additions & 5 deletions script/examples/BlockTime.s.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
Expand All @@ -21,10 +20,10 @@ contract DeployBlockTime is Script, BaseDeployer {
modifier computeCreate2(bytes32 salt) {
_callBreaker = vm.envAddress("CALL_BREAKER_ADDRESS");

_blockTime =
computeCreate2Address(salt, hashInitCode(type(BlockTime).creationCode, abi.encode()));
_blockTimeScheduler =
computeCreate2Address(salt, hashInitCode(type(BlockTimeScheduler).creationCode, abi.encode(_callBreaker, _blockTime)));
_blockTime = computeCreate2Address(salt, hashInitCode(type(BlockTime).creationCode, abi.encode()));
_blockTimeScheduler = computeCreate2Address(
salt, hashInitCode(type(BlockTimeScheduler).creationCode, abi.encode(_callBreaker, _blockTime))
);

_;
}
Expand Down
7 changes: 3 additions & 4 deletions src/interfaces/IBlockTime.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import "openzeppelin-contracts/contracts/access/IAccessControl.sol";
import "openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol";

interface IBlockTime {

struct Chronicle {
uint256 epoch;
address timeKeeper;
Expand All @@ -18,9 +17,9 @@ interface IBlockTime {
/// @param receivers List of addresses that will receive TimeToken rewards
/// @param amounts List of amounts of TimeToken to be minted for each receiver
function moveTime(
Chronicle[] calldata chronicles,
uint256 meanCurrentEarthTime,
address[] calldata receivers,
Chronicle[] calldata chronicles,
uint256 meanCurrentEarthTime,
address[] calldata receivers,
uint256[] calldata amounts
) external;

Expand Down
17 changes: 11 additions & 6 deletions src/utilities/BlockTime.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import "src/interfaces/IBlockTime.sol";

contract BlockTime is IBlockTime, AccessControl, ReentrancyGuard {
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant TIME_KEEPER = keccak256("TIME_KEEPER");
bytes32 public constant SCHEDULER_ROLE = keccak256("SCHEDULER_ROLE");

/// @dev minimum number of signed time values needed
Expand All @@ -26,10 +25,12 @@ contract BlockTime is IBlockTime, AccessControl, ReentrancyGuard {
uint256 public currentEarthTimeAvg;

/// @notice The ERC20 timeToken that will be transferred to users on successfull time updation
TimeToken public timeToken;
TimeToken public timeToken;

event Tick(uint256 currentEarthTimeBlockStart, uint256 currentEarthTimeBlockEnd);
event EarthTimeUpdated(uint256 newEarthTime, Chronicle[] chronicles, address[] timeTokenReceivers, uint256[] amounts);
event BlockTimeUpdated(
uint256 newEarthTime, Chronicle[] chronicles, address[] timeTokenReceivers, uint256[] amounts
);
event MaxBlockWidthSet(uint256 maxBlockWidth);

constructor() {
Expand All @@ -39,10 +40,15 @@ contract BlockTime is IBlockTime, AccessControl, ReentrancyGuard {
}

/// @notice changes earth avg time
function moveTime(Chronicle[] calldata chronicles, uint256 meanCurrentEarthTime, address[] calldata receivers, uint256[] calldata amounts) external onlyRole(SCHEDULER_ROLE) nonReentrant {
function moveTime(
Chronicle[] calldata chronicles,
uint256 meanCurrentEarthTime,
address[] calldata receivers,
uint256[] calldata amounts
) external onlyRole(SCHEDULER_ROLE) nonReentrant {
currentEarthTimeAvg = meanCurrentEarthTime;
timeToken.batchMint(receivers, amounts);
emit EarthTimeUpdated(meanCurrentEarthTime, chronicles, receivers, amounts);
emit BlockTimeUpdated(meanCurrentEarthTime, chronicles, receivers, amounts);
}

/// @notice returns current block time
Expand All @@ -60,5 +66,4 @@ contract BlockTime is IBlockTime, AccessControl, ReentrancyGuard {
function getMaxBlockWidth() public view returns (uint256) {
return maxBlockWidth;
}

}
2 changes: 1 addition & 1 deletion src/utilities/TimeToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ contract TimeToken is ERC20, Ownable {

emit BatchMinted(to, amounts);
}
}
}
64 changes: 36 additions & 28 deletions test/examples/BlockTime/BlockTimeScheduler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,64 @@ pragma solidity 0.8.26;
import "src/interfaces/IBlockTime.sol";
import "src/timetravel/CallBreaker.sol";
import "src/timetravel/SmarterContract.sol";
import "openzeppelin-contracts/contracts/access/Ownable.sol";
import "openzeppelin-contracts/contracts/access/AccessControl.sol";
import "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol";

/**
* @notice This is an POC example of a block scheduler
*/
contract BlockTimeScheduler is SmarterContract, Ownable {
contract BlockTimeScheduler is SmarterContract, AccessControl {
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant TIME_SOLVER = keccak256("TIME_SOLVER");

struct BlockTimeData {
IBlockTime.Chronicle[] chronicles;
uint256 meanCurrentErathTime;
BatchMintData mintTokensData;
}
// TODO: To be used to reduce repeated external call to CallBreaker
// struct BlockTimeData {
// IBlockTime.Chronicle[] chronicles;
// uint256 meanCurrentEarthTime;
// BatchMintData mintTokensData;
// }

struct BatchMintData {
address[] receiver;
uint256[] amounts;
}
// struct BatchMintData {
// address[] receiver;
// uint256[] amounts;
// }

bool public shouldContinue;
address public callBreaker;
IBlockTime public blockTime;

constructor(address _callBreaker, address _blockTime) SmarterContract(_callBreaker) Ownable(msg.sender) {
constructor(address _callBreaker, address _blockTime) SmarterContract(_callBreaker) {
callBreaker = _callBreaker;
blockTime = IBlockTime(_blockTime);
shouldContinue = true;

_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
_grantRole(ADMIN_ROLE, _msgSender());
}

/// @dev The onlyOwner modifier will be later changed to execute calls through a governance proposal
function updateTime() external onlyOwner {
bytes32 key = keccak256(abi.encodePacked("MoveTimeData"));
bytes memory data = CallBreaker(payable(callBreaker)).fetchFromAssociatedDataStore(key);

BlockTimeData memory moveTimeData = abi.decode(data, (BlockTimeData));
blockTime.moveTime(moveTimeData.chronicles, moveTimeData.meanCurrentErathTime, moveTimeData.mintTokensData.receiver, moveTimeData.mintTokensData.amounts);

CallObject memory callObj = CallObject({
amount: 0,
addr: address(this),
gas: 1000000,
callvalue: abi.encodeWithSignature("verifySignature(bytes)", data)
});
function updateTime() external onlyRole(TIME_SOLVER) {
bytes memory chroniclesData =
CallBreaker(payable(callBreaker)).fetchFromAssociatedDataStore(keccak256(abi.encodePacked("Chronicles")));
bytes memory meanTimeData = CallBreaker(payable(callBreaker)).fetchFromAssociatedDataStore(
keccak256(abi.encodePacked("CurrentMeanTime"))
);
bytes memory recievers =
CallBreaker(payable(callBreaker)).fetchFromAssociatedDataStore(keccak256(abi.encodePacked("Recievers")));
bytes memory amounts =
CallBreaker(payable(callBreaker)).fetchFromAssociatedDataStore(keccak256(abi.encodePacked("Amounts")));

assertFutureCallTo(callObj, 1);
blockTime.moveTime(
abi.decode(chroniclesData, (IBlockTime.Chronicle[])),
abi.decode(meanTimeData, (uint256)),
abi.decode(recievers, (address[])),
abi.decode(amounts, (uint256[]))
);
}

/// @notice function to be checked by Laminator before rescheduling a call to disburseKITNs
/// @dev The onlyOwner modifier will be later changed to execute calls through a governance proposal
function setContinue(bool _shouldContinue) external onlyOwner {
function setContinue(bool _shouldContinue) external onlyRole(ADMIN_ROLE) {
shouldContinue = _shouldContinue;
}
}
}

0 comments on commit 9d0d138

Please sign in to comment.