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

feat(protocol): make more addresses in protocol immutable #18924

Merged
merged 15 commits into from
Feb 13, 2025
63 changes: 30 additions & 33 deletions packages/protocol/contracts/layer1/based/TaikoInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,31 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I
using LibMath for uint256;
using SafeERC20 for IERC20;

address public immutable inboxWrapper;
address public immutable verifier;
address public immutable bondToken;
ISignalService public immutable signalService;

State public state; // storage layout much match Ontake fork
uint256[50] private __gap;

// External functions ------------------------------------------------------------------------

constructor(address _resolver) EssentialContract(_resolver) { }
constructor(
address _inboxWrapper,
address _verifier,
address _bondToken,
address _signalService
)
nonZeroAddr(_verifier)
nonZeroAddr(_signalService)
EssentialContract(address(0))
{
inboxWrapper = _inboxWrapper;
verifier = _verifier;
bondToken = _bondToken;
signalService = ISignalService(_signalService);
}

function init(address _owner, bytes32 _genesisBlockHash) external initializer {
__Taiko_init(_owner, _genesisBlockHash);
Expand Down Expand Up @@ -70,16 +89,14 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I
BatchParams memory params = abi.decode(_params, (BatchParams));

{
// TODO(david): replace with immutable
address wrapper = resolve(LibStrings.B_INBOX_WRAPPER, true);
if (wrapper == address(0)) {
if (inboxWrapper == address(0)) {
require(params.proposer == address(0), CustomProposerNotAllowed());
params.proposer = msg.sender;

// blob hashes are only accepted if the caller is trusted.
require(params.blobParams.blobHashes.length == 0, InvalidBlobParams());
} else {
require(msg.sender == wrapper, NotInboxWrapper());
require(msg.sender == inboxWrapper, NotInboxWrapper());
require(params.proposer != address(0), CustomProposerMissing());
}

Expand Down Expand Up @@ -293,8 +310,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I
}
}

// TODO(david): replace with immutable
address verifier = resolve(LibStrings.B_PROOF_VERIFIER, false);
IVerifier(verifier).verifyProof(ctxs, _proof);

// Emit the event
Expand Down Expand Up @@ -398,9 +413,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I

state.bondBalance[msg.sender] -= _amount;

address bond = bondToken();
if (bond != address(0)) {
IERC20(bond).safeTransfer(msg.sender, _amount);
if (bondToken != address(0)) {
IERC20(bondToken).safeTransfer(msg.sender, _amount);
} else {
LibAddress.sendEtherAndVerify(msg.sender, _amount);
}
Expand Down Expand Up @@ -508,12 +522,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I
return state.stats2.paused;
}

/// @inheritdoc ITaikoInbox
function bondToken() public view returns (address) {
// TODO(david): replace with immutable
return resolve(LibStrings.B_BOND_TOKEN, true);
}

/// @inheritdoc ITaikoInbox
function getBatch(uint64 _batchId) public view returns (Batch memory batch_) {
Config memory config = pacayaConfig();
Expand Down Expand Up @@ -705,9 +713,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I
emit Stats1Updated(stats1);

// Ask signal service to write cross chain signal
ISignalService(resolve(LibStrings.B_SIGNAL_SERVICE, false))
// TODO(david): replace with immutable
.syncChainData(
signalService.syncChainData(
_config.chainId, LibStrings.H_STATE_ROOT, synced.blockId, synced.stateRoot
);
}
Expand Down Expand Up @@ -748,14 +754,12 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I
private
returns (uint256 amountDeposited_)
{
address bond = bondToken();

if (bond != address(0)) {
if (bondToken != address(0)) {
require(msg.value == 0, MsgValueNotZero());

uint256 balance = IERC20(bond).balanceOf(address(this));
IERC20(bond).safeTransferFrom(_user, address(this), _amount);
amountDeposited_ = IERC20(bond).balanceOf(address(this)) - balance;
uint256 balance = IERC20(bondToken).balanceOf(address(this));
IERC20(bondToken).safeTransferFrom(_user, address(this), _amount);
amountDeposited_ = IERC20(bondToken).balanceOf(address(this)) - balance;
} else {
require(msg.value == _amount, EtherNotPaidAsBond());
amountDeposited_ = _amount;
Expand Down Expand Up @@ -798,7 +802,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I
require(lastBlockTimestamp_ <= block.timestamp, TimestampTooLarge());

uint64 totalShift;
address signalService;

for (uint256 i; i < blocksLength; ++i) {
totalShift += _params.blocks[i].timeShift;
Expand All @@ -808,15 +811,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, IProposeBatch, I

require(numSignals <= _maxSignalsToReceive, TooManySignals());

if (signalService == address(0)) {
// TODO(david): replace with immutable
signalService = resolve(LibStrings.B_SIGNAL_SERVICE, false);
}

for (uint256 j; j < numSignals; ++j) {
// TODO(david): replace with immutable
require(
ISignalService(signalService).isSignalSent(_params.blocks[i].signalSlots[j]),
signalService.isSignalSent(_params.blocks[i].signalSlots[j]),
SignalNotSent()
);
}
Expand Down
9 changes: 8 additions & 1 deletion packages/protocol/contracts/layer1/devnet/DevnetInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ import "../based/TaikoInbox.sol";
/// @dev Labeled in address resolver as "taiko"
/// @custom:security-contact [email protected]
contract DevnetInbox is TaikoInbox {
constructor(address _resolver) TaikoInbox(_resolver) { }
constructor(
address _wrapper,
address _verifier,
address _bondToken,
address _signalService
)
TaikoInbox(_wrapper, _verifier, _bondToken, _signalService)
{ }

/// @inheritdoc ITaikoInbox
function pacayaConfig() public pure override returns (ITaikoInbox.Config memory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ contract ForcedInclusionStore is EssentialContract, IForcedInclusionStore {

uint8 public immutable inclusionDelay; // measured in the number of batches
uint64 public immutable feeInGwei;
ITaikoInbox public immutable taikoInbox;
address public immutable taikoInboxWrapper;
ITaikoInbox public immutable inbox;
address public immutable inboxWrapper;

mapping(uint256 id => ForcedInclusion inclusion) public queue; // slot 1
uint64 public head; // slot 2
Expand All @@ -33,18 +33,19 @@ contract ForcedInclusionStore is EssentialContract, IForcedInclusionStore {
constructor(
uint8 _inclusionDelay,
uint64 _feeInGwei,
address _taikoInbox,
address _taikoInboxWrapper
address _inbox,
address _inboxWrapper
)
nonZeroValue(_inclusionDelay)
nonZeroValue(_feeInGwei)
nonZeroAddr(_inbox)
nonZeroAddr(_inboxWrapper)
EssentialContract(address(0))
{
require(_inclusionDelay != 0, InvalidParams());
require(_feeInGwei != 0, InvalidParams());

inclusionDelay = _inclusionDelay;
feeInGwei = _feeInGwei;
taikoInbox = ITaikoInbox(_taikoInbox);
taikoInboxWrapper = _taikoInboxWrapper;
inbox = ITaikoInbox(_inbox);
inboxWrapper = _inboxWrapper;
}

function init(address _owner) external initializer {
Expand Down Expand Up @@ -79,7 +80,7 @@ contract ForcedInclusionStore is EssentialContract, IForcedInclusionStore {

function consumeOldestForcedInclusion(address _feeRecipient)
external
onlyFrom(taikoInboxWrapper)
onlyFrom(inboxWrapper)
nonReentrant
returns (ForcedInclusion memory inclusion_)
{
Expand Down Expand Up @@ -126,6 +127,6 @@ contract ForcedInclusionStore is EssentialContract, IForcedInclusionStore {
}

function _nextBatchId() private view returns (uint64) {
return taikoInbox.getStats2().numBatches;
return inbox.getStats2().numBatches;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,22 @@ contract TaikoWrapper is EssentialContract, IProposeBatch {
error OldestForcedInclusionDue();

uint16 public constant MIN_TXS_PER_FORCED_INCLUSION = 512;
IProposeBatch public immutable taikoInbox;
IProposeBatch public immutable inbox;
IForcedInclusionStore public immutable forcedInclusionStore;
address public immutable preconfRouter;

uint256[50] private __gap;

constructor(
address _taikoInbox,
address _inbox,
address _forcedInclusionStore,
address _preconfRouter
)
nonZeroAddr(_inbox)
nonZeroAddr(_forcedInclusionStore)
EssentialContract(address(0))
{
taikoInbox = IProposeBatch(_taikoInbox);
inbox = IProposeBatch(_inbox);
forcedInclusionStore = IForcedInclusionStore(_forcedInclusionStore);
preconfRouter = _preconfRouter;
}
Expand All @@ -84,23 +86,23 @@ contract TaikoWrapper is EssentialContract, IProposeBatch {
require(!forcedInclusionStore.isOldestForcedInclusionDue(), OldestForcedInclusionDue());
} else {
_validateForcedInclusionParams(forcedInclusionStore, bytesX);
taikoInbox.proposeBatch(bytesX, "");
inbox.proposeBatch(bytesX, "");
}

// Propose the normal batch after the potential forced inclusion batch.
return taikoInbox.proposeBatch(bytesY, _txList);
return inbox.proposeBatch(bytesY, _txList);
}

function _validateForcedInclusionParams(
IForcedInclusionStore _store,
IForcedInclusionStore _forcedInclusionStore,
bytes memory _bytesX
)
internal
{
ITaikoInbox.BatchParams memory p = abi.decode(_bytesX, (ITaikoInbox.BatchParams));

IForcedInclusionStore.ForcedInclusion memory inclusion =
_store.consumeOldestForcedInclusion(p.proposer);
_forcedInclusionStore.consumeOldestForcedInclusion(p.proposer);

uint256 numBlocks = p.blocks.length;
require(numBlocks != 0, NoBlocks());
Expand Down
9 changes: 8 additions & 1 deletion packages/protocol/contracts/layer1/hekla/HeklaInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ import "../based/TaikoInbox.sol";
/// @dev Labeled in address resolver as "taiko"
/// @custom:security-contact [email protected]
contract HeklaInbox is TaikoInbox {
constructor(address _resolver) TaikoInbox(_resolver) { }
constructor(
address _wrapper,
address _verifier,
address _bondToken,
address _signalService
)
TaikoInbox(_wrapper, _verifier, _bondToken, _signalService)
{ }

function pacayaConfig() public pure override returns (ITaikoInbox.Config memory) {
return ITaikoInbox.Config({
Expand Down
9 changes: 8 additions & 1 deletion packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ import "./libs/LibFasterReentryLock.sol";
/// @notice See the documentation in {TaikoL1}.
/// @custom:security-contact [email protected]
contract MainnetInbox is TaikoInbox {
constructor(address _resolver) TaikoInbox(_resolver) { }
constructor(
address _wrapper,
address _verifier,
address _bondToken,
address _signalService
)
TaikoInbox(_wrapper, _verifier, _bondToken, _signalService)
{ }

function pacayaConfig() public pure override returns (ITaikoInbox.Config memory) {
// All hard-coded configurations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ contract RollupResolver is ResolverBase {
return 0xE3D777143Ea25A6E031d1e921F396750885f43aC;
}
if (_name == LibStrings.B_PROOF_VERIFIER) {
return address(0); // TODO(davil)
return address(0); // TODO(david)
}
return address(0);
}
Expand Down
32 changes: 20 additions & 12 deletions packages/protocol/contracts/layer1/provers/ProverSet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,21 @@ import "../based/IProposeBatch.sol";
contract ProverSet is ProverSetBase, IProposeBatch {
using Address for address;

address public immutable entrypoint;

error ForcedInclusionParamsNotAllowed();

constructor(address _resolver) ProverSetBase(_resolver) { }
constructor(
address _resolver,
address _inbox,
address _bondToken,
address _entrypoint
)
nonZeroAddr(_entrypoint)
ProverSetBase(_resolver, _inbox, _bondToken)
{
entrypoint = _entrypoint;
}

// ================ Pacaya calls ================

Expand All @@ -22,14 +34,12 @@ contract ProverSet is ProverSetBase, IProposeBatch {
onlyProver
returns (ITaikoInbox.BatchInfo memory, ITaikoInbox.BatchMetadata memory)
{
// TODO(david): replace with immutable
address entrypoint = resolve(LibStrings.B_PRECONF_ROUTER, false);
return IProposeBatch(entrypoint).proposeBatch(_params, _txList);
}

/// @notice Proves multiple Taiko batches.
function proveBatches(bytes calldata _params, bytes calldata _proof) external onlyProver {
ITaikoInbox(inbox()).proveBatches(_params, _proof);
ITaikoInbox(inbox).proveBatches(_params, _proof);
}

// ================ Ontake calls ================
Expand All @@ -45,19 +55,17 @@ contract ProverSet is ProverSetBase, IProposeBatch {
{
// Ensure this block is the first block proposed in the current L1 block.
uint64 blockNumber = abi.decode(
inbox().functionStaticCall(abi.encodeWithSignature("lastProposedIn()")), (uint64)
inbox.functionStaticCall(abi.encodeWithSignature("lastProposedIn()")), (uint64)
);
require(blockNumber != block.number, NOT_FIRST_PROPOSAL());
inbox().functionCall(
inbox.functionCall(
abi.encodeWithSignature("proposeBlocksV2(bytes[],bytes[])", _params, _txList)
);
}

/// @notice Propose a Taiko block.
function proposeBlockV2(bytes calldata _params, bytes calldata _txList) external onlyProver {
inbox().functionCall(
abi.encodeWithSignature("proposeBlockV2(bytes,bytes)", _params, _txList)
);
inbox.functionCall(abi.encodeWithSignature("proposeBlockV2(bytes,bytes)", _params, _txList));
}

/// @notice Propose multiple Taiko blocks.
Expand All @@ -68,14 +76,14 @@ contract ProverSet is ProverSetBase, IProposeBatch {
external
onlyProver
{
inbox().functionCall(
inbox.functionCall(
abi.encodeWithSignature("proposeBlocksV2(bytes[],bytes[])", _paramsArr, _txListArr)
);
}

/// @notice Proves or contests a Taiko block.
function proveBlock(uint64 _blockId, bytes calldata _input) external onlyProver {
inbox().functionCall(abi.encodeWithSignature("proveBlock(uint64,bytes)", _blockId, _input));
inbox.functionCall(abi.encodeWithSignature("proveBlock(uint64,bytes)", _blockId, _input));
}

/// @notice Batch proves or contests Taiko blocks.
Expand All @@ -87,7 +95,7 @@ contract ProverSet is ProverSetBase, IProposeBatch {
external
onlyProver
{
inbox().functionCall(
inbox.functionCall(
abi.encodeWithSignature(
"proveBlocks(uint64[],bytes[],bytes)", _blockId, _input, _batchProof
)
Expand Down
Loading