diff --git a/contracts/contracts/BlockTracker.sol b/contracts/contracts/BlockTracker.sol index 68c0850c4..07a7a1c07 100644 --- a/contracts/contracts/BlockTracker.sol +++ b/contracts/contracts/BlockTracker.sol @@ -9,6 +9,16 @@ import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/U * @dev A contract that tracks Ethereum blocks and their winners. */ contract BlockTracker is OwnableUpgradeable, UUPSUpgradeable { + + /// @dev Permissioned address of the oracle account. + address public oracleAccount; + + /// @dev Modifier to ensure that the sender is the oracle account. + modifier onlyOracle() { + require(msg.sender == oracleAccount, "sender isn't oracle account"); + _; + } + /// @dev Event emitted when a new L1 block is tracked. event NewL1Block( uint256 indexed blockNumber, @@ -32,12 +42,15 @@ contract BlockTracker is OwnableUpgradeable, UUPSUpgradeable { /** * @dev Initializes the BlockTracker contract with the specified owner. - * @param _owner The address of the contract owner. + * @param blocksPerWindow_ Number of blocks per window. + * @param oracleAccount_ Address of the permissoined oracle account. + * @param owner_ Address of the contract owner. */ - function initialize(address _owner, uint256 _blocksPerWindow) external initializer { + function initialize(uint256 blocksPerWindow_, address oracleAccount_, address owner_) external initializer { currentWindow = 1; - blocksPerWindow = _blocksPerWindow; - __Ownable_init(_owner); + blocksPerWindow = blocksPerWindow_; + oracleAccount = oracleAccount_; + __Ownable_init(owner_); } /// @dev See https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializing_the_implementation_contract @@ -48,21 +61,21 @@ contract BlockTracker is OwnableUpgradeable, UUPSUpgradeable { /** * @dev Retrieves the current window number. - * @return The current window number. + * @return currentWindow The current window number. */ function getCurrentWindow() external view returns (uint256) { return currentWindow; } /** - * @dev Allows the owner to add a new builder address. + * @dev Allows the oracle account to add a new builder address mapping. * @param builderName The name of the block builder as it appears on extra data. * @param builderAddress The Ethereum address of the builder. */ function addBuilderAddress( string memory builderName, address builderAddress - ) external onlyOwner { + ) external onlyOracle { blockBuilderNameToAddress[builderName] = builderAddress; } @@ -93,7 +106,7 @@ contract BlockTracker is OwnableUpgradeable, UUPSUpgradeable { function recordL1Block( uint256 _blockNumber, string calldata _winnerGraffiti - ) external onlyOwner { + ) external onlyOracle { address _winner = blockBuilderNameToAddress[_winnerGraffiti]; recordBlockWinner(_blockNumber, _winner); uint256 newWindow = (_blockNumber - 1) / blocksPerWindow + 1; diff --git a/contracts/contracts/Oracle.sol b/contracts/contracts/Oracle.sol index 89e76305f..d8c5fbfbd 100644 --- a/contracts/contracts/Oracle.sol +++ b/contracts/contracts/Oracle.sol @@ -22,6 +22,15 @@ contract Oracle is OwnableUpgradeable, UUPSUpgradeable { /// @dev Maps builder names to their respective Ethereum addresses. mapping(string => address) public blockBuilderNameToAddress; + /// @dev Permissioned address of the oracle account. + address public oracleAccount; + + /// @dev Modifier to ensure that the sender is the oracle account. + modifier onlyOracle() { + require(msg.sender == oracleAccount, "sender isn't oracle account"); + _; + } + // To shutup the compiler /// @dev Empty receive function to silence compiler warnings about missing payable functions. receive() external payable { @@ -45,18 +54,21 @@ contract Oracle is OwnableUpgradeable, UUPSUpgradeable { /** * @dev Initializes the contract with a PreConfirmations contract. - * @param _preConfContract The address of the pre-confirmations contract. - * @param _blockTrackerContract The address of the block tracker contract. - * @param _owner Owner of the contract, explicitly needed since contract is deployed with create2 factory. + * @param preConfContract_ The address of the pre-confirmations contract. + * @param blockTrackerContract_ The address of the block tracker contract. + * @param oracleAccount_ The address of the oracle account. + * @param owner_ Owner of the contract, explicitly needed since contract is deployed with create2 factory. */ function initialize( - address _preConfContract, - address _blockTrackerContract, - address _owner + address preConfContract_, + address blockTrackerContract_, + address oracleAccount_, + address owner_ ) external initializer { - preConfContract = IPreConfCommitmentStore(_preConfContract); - blockTrackerContract = IBlockTracker(_blockTrackerContract); - __Ownable_init(_owner); + preConfContract = IPreConfCommitmentStore(preConfContract_); + blockTrackerContract = IBlockTracker(blockTrackerContract_); + oracleAccount = oracleAccount_; + __Ownable_init(owner_); } /// @dev See https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializing_the_implementation_contract @@ -83,7 +95,7 @@ contract Oracle is OwnableUpgradeable, UUPSUpgradeable { address builder, bool isSlash, uint256 residualBidPercentAfterDecay - ) external onlyOwner { + ) external onlyOracle { require( blockTrackerContract.getBlockWinner(blockNumber) == builder, "Builder is not the winner of the block" diff --git a/contracts/entrypoint.sh b/contracts/entrypoint.sh index 75d3789e2..363c34f60 100755 --- a/contracts/entrypoint.sh +++ b/contracts/entrypoint.sh @@ -15,43 +15,14 @@ KEYSTORE_PASSWORD=${KEYSTORE_PASSWORD:-"pwd"} CONTRACT_REPO_ROOT_PATH=${CONTRACT_REPO_ROOT_PATH:-$PWD} if [ "${DEPLOY_TYPE}" = "core" ]; then - echo "Deploying core contracts" - "${FORGE_BIN_PATH}" script \ - "${SCRIPT_PATH_PREFIX}"DeployScripts.s.sol:DeployScript \ - --root "${CONTRACT_REPO_ROOT_PATH}" \ - --priority-gas-price 2000000000 \ - --with-gas-price 5000000000 \ - --chain-id "${CHAIN_ID}" \ - --rpc-url "${RPC_URL}" \ - --keystores "${KEYSTORE_DIR}/${KEYSTORE_FILENAME}" \ - --password "${KEYSTORE_PASSWORD}" \ - --sender "${SENDER}" \ - --skip-simulation \ - --use 0.8.20 \ - --broadcast \ - --force \ - --json \ - --via-ir - -elif [ "${DEPLOY_TYPE}" = "transfer-ownership" ]; then if [ -z "$ORACLE_KEYSTORE_ADDRESS" ]; then echo "ORACLE_KEYSTORE_ADDRESS not specified" exit 1 fi - if [ -z "$BLOCK_TRACKER_ADDRESS" ]; then - echo "BLOCK_TRACKER_ADDRESS not specified" - exit 1 - fi - if [ -z "$ORACLE_ADDRESS" ]; then - echo "ORACLE_ADDRESS not specified" - exit 1 - fi - echo "Transferring ownership to ${ORACLE_KEYSTORE_ADDRESS}" + echo "Deploying core contracts" ORACLE_KEYSTORE_ADDRESS="$ORACLE_KEYSTORE_ADDRESS" \ - BLOCK_TRACKER_ADDRESS="$BLOCK_TRACKER_ADDRESS" \ - ORACLE_ADDRESS="$ORACLE_ADDRESS" \ "${FORGE_BIN_PATH}" script \ - "${SCRIPT_PATH_PREFIX}"DeployScripts.s.sol:TransferOwnership \ + "${SCRIPT_PATH_PREFIX}"DeployScripts.s.sol:DeployScript \ --root "${CONTRACT_REPO_ROOT_PATH}" \ --priority-gas-price 2000000000 \ --with-gas-price 5000000000 \ diff --git a/contracts/scripts/DeployScripts.s.sol b/contracts/scripts/DeployScripts.s.sol index 91a66b20e..ffeb7d46a 100644 --- a/contracts/scripts/DeployScripts.s.sol +++ b/contracts/scripts/DeployScripts.s.sol @@ -23,9 +23,12 @@ contract DeployScript is Script { uint64 commitmentDispatchWindow = 2000; uint256 blocksPerWindow = 10; + address oracleKeystoreAddress = vm.envAddress("ORACLE_KEYSTORE_ADDRESS"); + require(oracleKeystoreAddress != address(0), "Oracle keystore address not provided"); + address blockTrackerProxy = Upgrades.deployUUPSProxy( "BlockTracker.sol", - abi.encodeCall(BlockTracker.initialize, (msg.sender, blocksPerWindow)) + abi.encodeCall(BlockTracker.initialize, (blocksPerWindow, oracleKeystoreAddress, msg.sender)) ); BlockTracker blockTracker = BlockTracker(payable(blockTrackerProxy)); console.log("BlockTracker:", address(blockTracker)); @@ -63,7 +66,7 @@ contract DeployScript is Script { address oracleProxy = Upgrades.deployUUPSProxy( "Oracle.sol", - abi.encodeCall(Oracle.initialize, (address(preConfCommitmentStore), address(blockTracker), msg.sender)) + abi.encodeCall(Oracle.initialize, (address(preConfCommitmentStore), address(blockTracker), oracleKeystoreAddress, msg.sender)) ); Oracle oracle = Oracle(payable(oracleProxy)); console.log("Oracle:", address(oracle)); @@ -75,29 +78,6 @@ contract DeployScript is Script { } } -contract TransferOwnership is Script { - function run() external { - vm.startBroadcast(); - - address oracleKeystoreAddress = vm.envAddress("ORACLE_KEYSTORE_ADDRESS"); - require(oracleKeystoreAddress != address(0), "Oracle keystore address not provided"); - - address blockTrackerProxy = vm.envAddress("BLOCK_TRACKER_ADDRESS"); - require(blockTrackerProxy != address(0), "Block tracker not provided"); - BlockTracker blockTracker = BlockTracker(payable(blockTrackerProxy)); - blockTracker.transferOwnership(oracleKeystoreAddress); - console.log("BlockTracker owner:", blockTracker.owner()); - - address oracleProxy = vm.envAddress("ORACLE_ADDRESS"); - require(oracleProxy != address(0), "Oracle proxy not provided"); - Oracle oracle = Oracle(payable(oracleProxy)); - oracle.transferOwnership(oracleKeystoreAddress); - console.log("Oracle owner:", oracle.owner()); - - vm.stopBroadcast(); - } -} - // Deploys whitelist contract and adds HypERC20 to whitelist contract DeployWhitelist is Script { function run() external { diff --git a/infrastructure/nomad/playbooks/templates/jobs/contracts-deployer.nomad.j2 b/infrastructure/nomad/playbooks/templates/jobs/contracts-deployer.nomad.j2 index 6f75af951..a21cd1618 100644 --- a/infrastructure/nomad/playbooks/templates/jobs/contracts-deployer.nomad.j2 +++ b/infrastructure/nomad/playbooks/templates/jobs/contracts-deployer.nomad.j2 @@ -112,6 +112,12 @@ job "{{ job.name }}" { start_time=$(date +%s) echo "Deploying contracts..." export DEPLOY_TYPE="core" + {% raw %} + {{ with secret "secret/data/mev-commit" }} + echo '{{ .Data.data.oracle_keystore }}' > local/oracle_keystore + {{ end }} + {% endraw %} + export ORACLE_KEYSTORE_ADDRESS=$(jq -r '.address' local/oracle_keystore) chmod +x ${CONTRACT_REPO_ROOT_PATH}/entrypoint.sh LOGS="$(${CONTRACT_REPO_ROOT_PATH}/entrypoint.sh)" if [ $? -ne 0 ]; then @@ -130,23 +136,6 @@ job "{{ job.name }}" { | jq -c 'reduce .logs[] as $item ({}; . + {($item | split(": ")[0]): ($item | split(": ")[1])})' \ > local/www/contracts.json - echo "Transferring ownership..." - export DEPLOY_TYPE="transfer-ownership" - {% raw %} - {{ with secret "secret/data/mev-commit" }} - echo '{{ .Data.data.oracle_keystore }}' > local/oracle_keystore - {{ end }} - {% endraw %} - export ORACLE_KEYSTORE_ADDRESS=$(jq -r '.address' local/oracle_keystore) - export BLOCK_TRACKER_ADDRESS="$(jq -r '.BlockTracker' local/www/contracts.json)" - export ORACLE_ADDRESS="$(jq -r '.Oracle' local/www/contracts.json)" - ${CONTRACT_REPO_ROOT_PATH}/entrypoint.sh - if [ $? -ne 0 ]; then - echo "Failed to transfer ownership!" - exit 1 - fi - echo "Ownership transfered successfully." - python3 -m http.server {{ job.ports[0]['http']['static'] }} --directory /local/www # endtodo EOH