Skip to content

Commit

Permalink
feat(protocol): make more addresses in protocol immutable (#18924)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Wang <[email protected]>
  • Loading branch information
davidtaikocha and dantaik authored Feb 13, 2025
1 parent 78716e3 commit 6a47c5b
Show file tree
Hide file tree
Showing 32 changed files with 530 additions and 395 deletions.
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

0 comments on commit 6a47c5b

Please sign in to comment.