diff --git a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol index cc29915099e..e22c5dca41e 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol @@ -38,6 +38,7 @@ contract SgxAndZkVerifier is EssentialContract, IVerifier { TaikoData.TierProof calldata proof ) external + onlyFromNamed("taiko") { TaikoData.TierProof memory _proof; _proof.tier = proof.tier; diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 8708a1aa930..d345cd8838c 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -17,6 +17,7 @@ pragma solidity 0.8.20; import "lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; import "../../common/EssentialContract.sol"; import "../../thirdparty/LibBytesUtils.sol"; +import "../ITaikoL1.sol"; import "../TaikoData.sol"; import "./IVerifier.sol"; @@ -59,6 +60,17 @@ contract SgxVerifier is EssentialContract, IVerifier { error SGX_INVALID_INSTANCES(); error SGX_INVALID_PROOF(); + /// @dev Modifier that ensures the caller is either taikoL1 or SgxAndZkVerifier. + modifier onlyTaikoOrCombinedVerifier() { + if ( + msg.sender != resolve("taiko", true) + && msg.sender != resolve("tier_sgx_and_pse_zkevm", true) + ) { + revert RESOLVER_DENIED(); + } + _; + } + /// @notice Initializes the contract with the provided address manager. /// @param _addressManager The address of the address manager contract. function init(address _addressManager) external initializer { @@ -92,7 +104,16 @@ contract SgxVerifier is EssentialContract, IVerifier { external returns (uint256[] memory ids) { - bytes32 signedHash = keccak256(abi.encode("ADD_INSTANCES", extraInstances)); + address taikoL1 = resolve("taiko", false); + bytes32 signedHash = keccak256( + abi.encode( + "ADD_INSTANCES", + ITaikoL1(taikoL1).getConfig().chainId, + address(this), + newInstance, + extraInstances + ) + ); address oldInstance = ECDSA.recover(signedHash, signature); if (!_isInstanceValid(id, oldInstance)) revert SGX_INVALID_INSTANCE(); @@ -108,6 +129,7 @@ contract SgxVerifier is EssentialContract, IVerifier { TaikoData.TierProof calldata proof ) external + onlyTaikoOrCombinedVerifier { // Do not run proof verification to contest an existing proof if (ctx.isContesting) return; @@ -134,10 +156,21 @@ contract SgxVerifier is EssentialContract, IVerifier { bytes32 metaHash ) public - pure + view returns (bytes32 signedHash) { - return keccak256(abi.encode(tran, newInstance, prover, metaHash)); + address taikoL1 = resolve("taiko", false); + return keccak256( + abi.encode( + "VERIFY_PROOF", + ITaikoL1(taikoL1).getConfig().chainId, + address(this), + tran, + newInstance, + prover, + metaHash + ) + ); } function _addInstances(address[] calldata _instances) private returns (uint256[] memory ids) { diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index 90e71ab9186..f619ff81952 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -33,21 +33,30 @@ contract TestSgxVerifier is TaikoL1TestBase { _instances[0] = SGX_Y; _instances[1] = SGX_Z; - bytes memory signature = _getSignature(_instances, 0x4); + bytes memory signature = _getSignature(SGX_X_1, _instances, 0x4); vm.prank(Bob, Bob); sv.addInstances(0, SGX_X_1, _instances, signature); } function _getSignature( + address _newInstance, address[] memory _instances, uint256 privKey ) private - pure + view returns (bytes memory signature) { - bytes32 digest = keccak256(abi.encode("ADD_INSTANCES", _instances)); + bytes32 digest = keccak256( + abi.encode( + "ADD_INSTANCES", + ITaikoL1(L1).getConfig().chainId, + address(sv), + _newInstance, + _instances + ) + ); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privKey, digest); signature = abi.encodePacked(r, s, v); }