Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(protocol): use signature check to verify if msg.sender is EOA #16641

Merged
merged 16 commits into from
Apr 4, 2024
2 changes: 2 additions & 0 deletions packages/protocol/contracts/L1/TaikoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ library TaikoData {
// The max number of L2 blocks that can stay unsynced on L1 (a value of zero disables
// syncing)
uint8 blockSyncThreshold;
bool onlyEOACanUseCalldataForDA;
}

/// @dev Struct representing prover assignment
Expand All @@ -59,6 +60,7 @@ library TaikoData {
bytes32 extraData;
bytes32 parentMetaHash;
HookCall[] hookCalls;
bytes signature;
}

/// @dev Struct containing data only required for proving a block
Expand Down
4 changes: 2 additions & 2 deletions packages/protocol/contracts/L1/TaikoErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ abstract contract TaikoErrors {
error L1_INVALID_PARAM();
error L1_INVALID_PAUSE_STATUS();
error L1_INVALID_PROVER();
error L1_INVALID_SIG();
error L1_INVALID_TIER();
error L1_INVALID_TRANSITION();
error L1_LIVENESS_BOND_NOT_RECEIVED();
error L1_MISSING_VERIFIER();
error L1_NOT_ASSIGNED_PROVER();
error L1_PROPOSER_NOT_EOA();
error L1_PROVING_PAUSED();
error L1_RECEIVE_DISABLED();
error L1_MISSING_VERIFIER();
error L1_TOO_MANY_BLOCKS();
error L1_TOO_MANY_TIERS();
error L1_TRANSITION_ID_ZERO();
Expand Down
5 changes: 3 additions & 2 deletions packages/protocol/contracts/L1/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors {
LibVerifying.init(state, getConfig(), _genesisBlockHash);
}

function init2() external reinitializer(2) {
function init2() external onlyOwner reinitializer(2) {
dantaik marked this conversation as resolved.
Show resolved Hide resolved
// reset some previously used slots for future reuse
state.slotA.__reservedA1 = 0;
state.slotA.__reservedA2 = 0;
Expand Down Expand Up @@ -198,7 +198,8 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors {
// Taiko blocks proposed per Ethereum block is smaller than 1.
blockMaxGasLimit: 240_000_000,
livenessBond: 250e18, // 250 Taiko token
blockSyncThreshold: 16
blockSyncThreshold: 16,
onlyEOACanUseCalldataForDA: true
dantaik marked this conversation as resolved.
Show resolved Hide resolved
});
}

Expand Down
19 changes: 13 additions & 6 deletions packages/protocol/contracts/L1/libs/LibProposing.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../../common/IAddressResolver.sol";
import "../../libs/LibAddress.sol";
Expand Down Expand Up @@ -38,8 +39,8 @@ library LibProposing {
error L1_BLOB_NOT_FOUND();
error L1_INVALID_HOOK();
error L1_INVALID_PROVER();
error L1_INVALID_SIG();
error L1_LIVENESS_BOND_NOT_RECEIVED();
error L1_PROPOSER_NOT_EOA();
error L1_TOO_MANY_BLOCKS();
error L1_UNAUTHORIZED();
error L1_UNEXPECTED_PARENT();
Expand Down Expand Up @@ -129,13 +130,19 @@ library LibProposing {
meta_.blobHash = blobhash(0);
if (meta_.blobHash == 0) revert L1_BLOB_NOT_FOUND();
} else {
meta_.blobHash = keccak256(_txList);

// This function must be called as the outmost transaction (not an internal one) for
// the node to extract the calldata easily.
// Warning, this code will break after the Pectra hardfork with EIP 7645: Alias ORIGIN
// to SENDER
if (msg.sender != tx.origin) revert L1_PROPOSER_NOT_EOA();

meta_.blobHash = keccak256(_txList);
// We cannot rely on `msg.sender != tx.origin` for EOA check, as it will break after EIP
// 7645: Alias ORIGIN to SENDER

if (
_config.onlyEOACanUseCalldataForDA
&& ECDSA.recover(meta_.blobHash, params.signature) != msg.sender
) {
revert L1_INVALID_SIG();
}
}

// Following the Merge, the L1 mixHash incorporates the
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/contracts/bridge/Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ contract Bridge is EssentialContract, IBridge {
error B_INVALID_STATUS();
error B_INVALID_USER();
error B_INVALID_VALUE();
error B_INVOCATION_TOO_EARLY();
error B_MESSAGE_NOT_PROVEN();
error B_MESSAGE_NOT_SENT();
error B_MESSAGE_NOT_SUSPENDED();
Expand All @@ -63,7 +64,6 @@ contract Bridge is EssentialContract, IBridge {
error B_NOT_RECEIVED();
error B_PERMISSION_DENIED();
error B_STATUS_MISMATCH();
error B_INVOCATION_TOO_EARLY();

modifier sameChain(uint64 _chainId) {
if (_chainId != block.chainid) revert B_INVALID_CHAINID();
Expand Down
3 changes: 2 additions & 1 deletion packages/protocol/test/L1/TaikoL1.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ contract TaikoL1_NoCooldown is TaikoL1 {
config.blockMaxProposals = 10;
config.blockRingBufferSize = 12;
config.livenessBond = 1e18; // 1 Taiko token
config.onlyEOACanUseCalldataForDA = false;
}
}

Expand Down Expand Up @@ -222,7 +223,7 @@ contract TaikoL1Test is TaikoL1TestBase {
vm.prank(proposer, proposer);
vm.expectRevert(revertReason);
L1.proposeBlock{ value: msgValue }(
abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, hookcalls)),
abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, hookcalls, "")),
new bytes(txListSize)
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ contract TaikoL1Tiers is TaikoL1 {
config.blockMaxProposals = 10;
config.blockRingBufferSize = 12;
config.livenessBond = 1e18; // 1 Taiko token
config.onlyEOACanUseCalldataForDA = false;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/test/L1/TaikoL1TestBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ abstract contract TaikoL1TestBase is TaikoTest {

vm.prank(proposer, proposer);
(meta, ethDeposits) = L1.proposeBlock{ value: msgValue }(
abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, hookcalls)),
abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, hookcalls, "")),
new bytes(txListSize)
);
}
Expand Down
Loading