diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index fafb583d8d9..1a0e50700e8 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -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); @@ -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()); } @@ -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 @@ -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); } @@ -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(); @@ -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 ); } @@ -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; @@ -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; @@ -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() ); } diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index 1a444589e31..460fb6ee6f9 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -7,7 +7,14 @@ import "../based/TaikoInbox.sol"; /// @dev Labeled in address resolver as "taiko" /// @custom:security-contact security@taiko.xyz 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) { diff --git a/packages/protocol/contracts/layer1/forced-inclusion/ForcedInclusionStore.sol b/packages/protocol/contracts/layer1/forced-inclusion/ForcedInclusionStore.sol index 58ebbe44444..f989509407c 100644 --- a/packages/protocol/contracts/layer1/forced-inclusion/ForcedInclusionStore.sol +++ b/packages/protocol/contracts/layer1/forced-inclusion/ForcedInclusionStore.sol @@ -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 @@ -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 { @@ -79,7 +80,7 @@ contract ForcedInclusionStore is EssentialContract, IForcedInclusionStore { function consumeOldestForcedInclusion(address _feeRecipient) external - onlyFrom(taikoInboxWrapper) + onlyFrom(inboxWrapper) nonReentrant returns (ForcedInclusion memory inclusion_) { @@ -126,6 +127,6 @@ contract ForcedInclusionStore is EssentialContract, IForcedInclusionStore { } function _nextBatchId() private view returns (uint64) { - return taikoInbox.getStats2().numBatches; + return inbox.getStats2().numBatches; } } diff --git a/packages/protocol/contracts/layer1/forced-inclusion/TaikoWrapper.sol b/packages/protocol/contracts/layer1/forced-inclusion/TaikoWrapper.sol index fae20382d51..a9a6824ecf0 100644 --- a/packages/protocol/contracts/layer1/forced-inclusion/TaikoWrapper.sol +++ b/packages/protocol/contracts/layer1/forced-inclusion/TaikoWrapper.sol @@ -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; } @@ -84,15 +86,15 @@ 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 @@ -100,7 +102,7 @@ contract TaikoWrapper is EssentialContract, IProposeBatch { 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()); diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index 6783a2ab563..e217d3447c5 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -7,7 +7,14 @@ import "../based/TaikoInbox.sol"; /// @dev Labeled in address resolver as "taiko" /// @custom:security-contact security@taiko.xyz 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({ diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index 9391a813448..08dceea288d 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -11,7 +11,14 @@ import "./libs/LibFasterReentryLock.sol"; /// @notice See the documentation in {TaikoL1}. /// @custom:security-contact security@taiko.xyz 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: diff --git a/packages/protocol/contracts/layer1/mainnet/resolvers/RollupResolver.sol b/packages/protocol/contracts/layer1/mainnet/resolvers/RollupResolver.sol index 20cff49fb36..278c7dfca79 100644 --- a/packages/protocol/contracts/layer1/mainnet/resolvers/RollupResolver.sol +++ b/packages/protocol/contracts/layer1/mainnet/resolvers/RollupResolver.sol @@ -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); } diff --git a/packages/protocol/contracts/layer1/provers/ProverSet.sol b/packages/protocol/contracts/layer1/provers/ProverSet.sol index dd87d427c5e..3e8cb41b35b 100644 --- a/packages/protocol/contracts/layer1/provers/ProverSet.sol +++ b/packages/protocol/contracts/layer1/provers/ProverSet.sol @@ -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 ================ @@ -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 ================ @@ -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. @@ -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. @@ -87,7 +95,7 @@ contract ProverSet is ProverSetBase, IProposeBatch { external onlyProver { - inbox().functionCall( + inbox.functionCall( abi.encodeWithSignature( "proveBlocks(uint64[],bytes[],bytes)", _blockId, _input, _batchProof ) diff --git a/packages/protocol/contracts/layer1/provers/ProverSetBase.sol b/packages/protocol/contracts/layer1/provers/ProverSetBase.sol index c4a15b5b4d0..b0ef5bacbce 100644 --- a/packages/protocol/contracts/layer1/provers/ProverSetBase.sol +++ b/packages/protocol/contracts/layer1/provers/ProverSetBase.sol @@ -21,6 +21,9 @@ interface IHasRecipient { abstract contract ProverSetBase is EssentialContract, IERC1271 { bytes4 private constant _EIP1271_MAGICVALUE = 0x1626ba7e; + address public immutable inbox; + address public immutable bondToken; + mapping(address prover => bool isProver) public isProver; // slot 1 address public admin; // slot 2 @@ -29,7 +32,6 @@ abstract contract ProverSetBase is EssentialContract, IERC1271 { event ProverEnabled(address indexed prover, bool indexed enabled); error INVALID_STATUS(); - error INVALID_BOND_TOKEN(); error PERMISSION_DENIED(); error NOT_FIRST_PROPOSAL(); @@ -46,23 +48,29 @@ abstract contract ProverSetBase is EssentialContract, IERC1271 { _; } - constructor(address _resolver) EssentialContract(_resolver) { } + constructor( + address _resolver, + address _inbox, + address _bondToken + ) + nonZeroAddr(_inbox) + nonZeroAddr(_bondToken) + EssentialContract(_resolver) + { + inbox = _inbox; + bondToken = _bondToken; + } /// @notice Initializes the contract. function init(address _owner, address _admin) external nonZeroAddr(_admin) initializer { __Essential_init(_owner); admin = _admin; - address _bondToken = bondToken(); - if (_bondToken != address(0)) { - IERC20(_bondToken).approve(inbox(), type(uint256).max); - } + IERC20(bondToken).approve(inbox, type(uint256).max); } function approveAllowance(address _address, uint256 _allowance) external onlyOwner { - address _bondToken = bondToken(); - require(_bondToken != address(0), INVALID_BOND_TOKEN()); - IERC20(_bondToken).approve(_address, _allowance); + IERC20(bondToken).approve(_address, _allowance); } /// @notice Enables or disables a prover. @@ -75,12 +83,7 @@ abstract contract ProverSetBase is EssentialContract, IERC1271 { /// @notice Withdraws Taiko tokens back to the admin address. function withdrawToAdmin(uint256 _amount) external onlyAuthorized { - address _bondToken = bondToken(); - if (_bondToken != address(0)) { - IERC20(_bondToken).transfer(admin, _amount); - } else { - LibAddress.sendEtherAndVerify(admin, _amount); - } + IERC20(bondToken).transfer(admin, _amount); } /// @notice Withdraws ETH back to the owner address. @@ -90,20 +93,18 @@ abstract contract ProverSetBase is EssentialContract, IERC1271 { /// @notice Deposits Taiko token to Taiko contract. function depositBond(uint256 _amount) external onlyAuthorized { - ITaikoInbox(inbox()).depositBond(_amount); + ITaikoInbox(inbox).depositBond(_amount); } /// @notice Withdraws Taiko token from Taiko contract. function withdrawBond(uint256 _amount) external onlyAuthorized { - ITaikoInbox(inbox()).withdrawBond(_amount); + ITaikoInbox(inbox).withdrawBond(_amount); } /// @notice Delegates token voting right to a delegatee. /// @param _delegatee The delegatee to receive the voting right. function delegate(address _delegatee) external onlyAuthorized { - address _bondToken = bondToken(); - require(_bondToken != address(0), INVALID_BOND_TOKEN()); - ERC20VotesUpgradeable(_bondToken).delegate(_delegatee); + ERC20VotesUpgradeable(bondToken).delegate(_delegatee); } // This function is necessary for this contract to become an assigned prover. @@ -120,14 +121,4 @@ abstract contract ProverSetBase is EssentialContract, IERC1271 { magicValue_ = _EIP1271_MAGICVALUE; } } - - function inbox() internal view virtual returns (address) { - // TODO(david): replace with immutable - return resolve(LibStrings.B_TAIKO, false); - } - - function bondToken() internal view virtual returns (address) { - // TODO(david): replace with immutable - return resolve(LibStrings.B_BOND_TOKEN, true); - } } diff --git a/packages/protocol/contracts/shared/libs/LibStrings.sol b/packages/protocol/contracts/shared/libs/LibStrings.sol index 593873f8826..91baeda69a1 100644 --- a/packages/protocol/contracts/shared/libs/LibStrings.sol +++ b/packages/protocol/contracts/shared/libs/LibStrings.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.24; /// @title LibStrings /// @custom:security-contact security@taiko.xyz library LibStrings { - // TODO(david): remove unused strings bytes32 internal constant B_AUTOMATA_DCAP_ATTESTATION = bytes32("automata_dcap_attestation"); bytes32 internal constant B_BOND_TOKEN = bytes32("bond_token"); bytes32 internal constant B_BRIDGE = bytes32("bridge"); @@ -17,8 +16,6 @@ library LibStrings { bytes32 internal constant B_ERC20_VAULT = bytes32("erc20_vault"); bytes32 internal constant B_ERC721_VAULT = bytes32("erc721_vault"); bytes32 internal constant B_FORCED_INCLUSION_STORE = bytes32("forced_inclusion_store"); - bytes32 internal constant B_INBOX_WRAPPER = bytes32("inbox_operator"); - bytes32 internal constant B_PRECONF_ROUTER = bytes32("preconf_router"); bytes32 internal constant B_PRECONF_WHITELIST = bytes32("preconf_whitelist"); bytes32 internal constant B_PRECONF_WHITELIST_OWNER = bytes32("preconf_whitelist_owner"); bytes32 internal constant B_PROOF_VERIFIER = bytes32("proof_verifier"); @@ -28,7 +25,6 @@ library LibStrings { bytes32 internal constant B_SIGNAL_SERVICE = bytes32("signal_service"); bytes32 internal constant B_TAIKO = bytes32("taiko"); bytes32 internal constant B_TAIKO_TOKEN = bytes32("taiko_token"); - bytes32 internal constant B_TAIKO_WRAPPER = bytes32("taiko_wrapper"); bytes32 internal constant B_WITHDRAWER = bytes32("withdrawer"); bytes32 internal constant H_SIGNAL_ROOT = keccak256("SIGNAL_ROOT"); bytes32 internal constant H_STATE_ROOT = keccak256("STATE_ROOT"); diff --git a/packages/protocol/contracts/shared/tokenvault/BridgedERC1155.sol b/packages/protocol/contracts/shared/tokenvault/BridgedERC1155.sol index 7854fe0f0a9..a9a4e6b570e 100644 --- a/packages/protocol/contracts/shared/tokenvault/BridgedERC1155.sol +++ b/packages/protocol/contracts/shared/tokenvault/BridgedERC1155.sol @@ -16,6 +16,8 @@ contract BridgedERC1155 is IBridgedERC1155Initializable, ERC1155Upgradeable { + address public immutable erc1155Vault; + /// @notice Address of the source token contract. address public srcToken; @@ -32,7 +34,9 @@ contract BridgedERC1155 is error BTOKEN_INVALID_PARAMS(); - constructor(address _resolver) EssentialContract(_resolver) { } + constructor(address _erc1155Vault) EssentialContract(address(0)) { + erc1155Vault = _erc1155Vault; + } /// @inheritdoc IBridgedERC1155Initializable function init( @@ -69,7 +73,7 @@ contract BridgedERC1155 is ) external whenNotPaused - onlyFromNamed(LibStrings.B_ERC1155_VAULT) + onlyFrom(erc1155Vault) nonReentrant { _mintBatch(_to, _tokenIds, _amounts, ""); @@ -82,7 +86,7 @@ contract BridgedERC1155 is ) external whenNotPaused - onlyFromNamed(LibStrings.B_ERC1155_VAULT) + onlyFrom(erc1155Vault) nonReentrant { _burn(msg.sender, _id, _amount); diff --git a/packages/protocol/contracts/shared/tokenvault/BridgedERC721.sol b/packages/protocol/contracts/shared/tokenvault/BridgedERC721.sol index 6ddf8f0bbef..1731c703af6 100644 --- a/packages/protocol/contracts/shared/tokenvault/BridgedERC721.sol +++ b/packages/protocol/contracts/shared/tokenvault/BridgedERC721.sol @@ -16,6 +16,8 @@ contract BridgedERC721 is IBridgedERC721Initializable, ERC721Upgradeable { + address public immutable erc721Vault; + /// @notice Address of the source token contract. address public srcToken; @@ -27,7 +29,9 @@ contract BridgedERC721 is error BTOKEN_INVALID_PARAMS(); error BTOKEN_INVALID_BURN(); - constructor(address _resolver) EssentialContract(_resolver) { } + constructor(address _erc721Vault) EssentialContract(address(0)) { + erc721Vault = _erc721Vault; + } /// @inheritdoc IBridgedERC721Initializable function init( @@ -56,19 +60,14 @@ contract BridgedERC721 is ) external whenNotPaused - onlyFromNamed(LibStrings.B_ERC721_VAULT) + onlyFrom(erc721Vault) nonReentrant { _safeMint(_account, _tokenId); } /// @inheritdoc IBridgedERC721 - function burn(uint256 _tokenId) - external - whenNotPaused - onlyFromNamed(LibStrings.B_ERC721_VAULT) - nonReentrant - { + function burn(uint256 _tokenId) external whenNotPaused onlyFrom(erc721Vault) nonReentrant { // Check if the caller is the owner of the token. Somehow this is not done inside the // _burn() function below. if (ownerOf(_tokenId) != msg.sender) { diff --git a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol index eb9e7020812..e8b4268dfec 100644 --- a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol +++ b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol @@ -254,17 +254,53 @@ contract DeployProtocolOnL1 is DeployCapability { copyRegister(rollupResolver, _sharedResolver, "signal_service"); copyRegister(rollupResolver, _sharedResolver, "bridge"); + // Initializable the proxy for proofVerifier to get the contract address at first. + address proofVerifier = deployProxy({ + name: "proof_verifier", + impl: address( + new DevnetVerifier( + address(rollupResolver), address(0), address(0), address(0), address(0) + ) + ), + data: abi.encodeCall(ComposeVerifier.init, (address(0))), + registerTo: rollupResolver + }); + + // Inbox deployProxy({ name: "mainnet_taiko", - impl: address(new MainnetInbox(address(rollupResolver))), + impl: address( + new MainnetInbox( + address(0), + proofVerifier, + IResolver(_sharedResolver).resolve(uint64(block.chainid), "bond_token", false), + IResolver(_sharedResolver).resolve(uint64(block.chainid), "signal_service", false) + ) + ), data: abi.encodeCall(TaikoInbox.init, (owner, vm.envBytes32("L2_GENESIS_HASH"))) }); address oldFork = vm.envAddress("OLD_FORK_TAIKO_INBOX"); if (oldFork == address(0)) { - oldFork = address(new DevnetInbox(address(rollupResolver))); + oldFork = address( + new DevnetInbox( + address(0), + proofVerifier, + IResolver(_sharedResolver).resolve(uint64(block.chainid), "bond_token", false), + IResolver(_sharedResolver).resolve( + uint64(block.chainid), "signal_service", false + ) + ) + ); } - address newFork = address(new DevnetInbox(address(rollupResolver))); + address newFork = address( + new DevnetInbox( + address(0), + proofVerifier, + IResolver(_sharedResolver).resolve(uint64(block.chainid), "bond_token", false), + IResolver(_sharedResolver).resolve(uint64(block.chainid), "signal_service", false) + ) + ); console2.log(" oldFork :", oldFork); console2.log(" newFork :", newFork); @@ -278,6 +314,7 @@ contract DeployProtocolOnL1 is DeployCapability { TaikoInbox taikoInbox = TaikoInbox(payable(taikoInboxAddr)); taikoInbox.init(owner, vm.envBytes32("L2_GENESIS_HASH")); + // Verifiers uint64 l2ChainId = taikoInbox.pacayaConfig().chainId; require(l2ChainId != block.chainid, "same chainid"); @@ -287,26 +324,30 @@ contract DeployProtocolOnL1 is DeployCapability { data: abi.encodeCall(OpVerifier.init, (owner)), registerTo: rollupResolver }); - - address proofVerifier = address(new ERC1967Proxy(address(0), "")); address sgxVerifier = deploySgxVerifier(owner, rollupResolver, l2ChainId, address(taikoInbox), proofVerifier); (address risc0Verifier, address sp1Verifier) = deployZKVerifiers(owner, rollupResolver, l2ChainId); - UUPSUpgradeable(proofVerifier).upgradeToAndCall({ + UUPSUpgradeable(proofVerifier).upgradeTo({ newImplementation: address( new DevnetVerifier( address(rollupResolver), opVerifier, sgxVerifier, risc0Verifier, sp1Verifier ) - ), - data: abi.encodeCall(ComposeVerifier.init, (owner)) + ) }); + ComposeVerifier(proofVerifier).transferOwnership(owner); + console2.log("** proofVerifier ownership transferred to:", owner); + deployProxy({ name: "prover_set", - impl: address(new ProverSet(address(rollupResolver))), + impl: address( + new ProverSet( + address(rollupResolver), taikoInboxAddr, taikoInbox.bondToken(), taikoInboxAddr + ) + ), data: abi.encodeCall(ProverSetBase.init, (owner, vm.envAddress("PROVER_SET_ADMIN"))) }); } @@ -406,13 +447,8 @@ contract DeployProtocolOnL1 is DeployCapability { registerTo: resolver }); - router = deployProxy({ - name: "preconf_router", - impl: address(new PreconfRouter(taikoWrapper, whitelist)), - data: abi.encodeCall(PreconfRouter.init, (owner)), - registerTo: resolver - }); - + // Initializable a forced inclusion store with a fake address for TaikoWrapper at first, + // to be used for deploying TaikoWrapper, then upgrade it to the real TaikoWrapper address. store = deployProxy({ name: "forced_inclusion_store", impl: address( @@ -420,10 +456,10 @@ contract DeployProtocolOnL1 is DeployCapability { uint8(vm.envUint("INCLUSION_WINDOW")), uint64(vm.envUint("INCLUSION_FEE_IN_GWEI")), taikoInbox, - taikoWrapper + address(1) ) ), - data: abi.encodeCall(ForcedInclusionStore.init, (owner)), + data: abi.encodeCall(ForcedInclusionStore.init, (address(0))), registerTo: resolver }); @@ -434,14 +470,27 @@ contract DeployProtocolOnL1 is DeployCapability { registerTo: resolver }); - // taikoWrapper should be the whitelisted proposer, since - // we call PreconfRouter as the selected operator, which calls - // forcedinclustioninbox.proposeBatchWithForcedInclusion, - // which calls taikoInbox.proposeBatch. - DefaultResolver(resolver).registerAddress( - uint64(block.chainid), LibStrings.B_INBOX_WRAPPER, taikoWrapper + UUPSUpgradeable(store).upgradeTo( + address( + new ForcedInclusionStore( + uint8(vm.envUint("INCLUSION_WINDOW")), + uint64(vm.envUint("INCLUSION_FEE_IN_GWEI")), + taikoInbox, + taikoWrapper + ) + ) ); + Ownable2StepUpgradeable(store).transferOwnership(owner); + console2.log("** forced_inclusion_store ownership transferred to:", owner); + + router = deployProxy({ + name: "preconf_router", + impl: address(new PreconfRouter(taikoWrapper, whitelist)), + data: abi.encodeCall(PreconfRouter.init, (owner)), + registerTo: resolver + }); + return (whitelist, router, store, taikoWrapper); } diff --git a/packages/protocol/script/layer1/devnet/UpgradeDevnetPacayaL1.s.sol b/packages/protocol/script/layer1/devnet/UpgradeDevnetPacayaL1.s.sol index 9ecb18208b5..c6f76bb2dd2 100644 --- a/packages/protocol/script/layer1/devnet/UpgradeDevnetPacayaL1.s.sol +++ b/packages/protocol/script/layer1/devnet/UpgradeDevnetPacayaL1.s.sol @@ -101,12 +101,19 @@ contract UpgradeDevnetPacayaL1 is DeployCapability { copyRegister(rollupResolver, sharedResolver, "bond_token"); copyRegister(rollupResolver, sharedResolver, "signal_service"); copyRegister(rollupResolver, sharedResolver, "bridge"); + + // Initializable the proxy for proofVerifier to get the contract address at first. + address proofVerifier = address(new ERC1967Proxy(address(0), "")); + // TaikoInbox - address newFork = address(new DevnetInbox(rollupResolver)); + address newFork = + address(new DevnetInbox(address(0), proofVerifier, taikoToken, signalService)); UUPSUpgradeable(taikoInbox).upgradeTo(address(new PacayaForkRouter(oldFork, newFork))); register(rollupResolver, "taiko", taikoInbox); // Prover set - UUPSUpgradeable(proverSet).upgradeTo(address(new ProverSet(rollupResolver))); + UUPSUpgradeable(proverSet).upgradeTo( + address(new ProverSet(rollupResolver, newFork, taikoToken, newFork)) + ); // Verifier TaikoInbox taikoInboxImpl = TaikoInbox(newFork); uint64 l2ChainId = taikoInboxImpl.pacayaConfig().chainId; @@ -118,7 +125,6 @@ contract UpgradeDevnetPacayaL1 is DeployCapability { registerTo: rollupResolver }); - address proofVerifier = address(new ERC1967Proxy(address(0), "")); address automataDcapAttestation = address(0); // not used! UUPSUpgradeable(sgxVerifier).upgradeTo( address(new SgxVerifier(l2ChainId, taikoInbox, proofVerifier, automataDcapAttestation)) diff --git a/packages/protocol/script/layer1/hekla/UpgradeHeklaOntakeL1.s.sol b/packages/protocol/script/layer1/hekla/UpgradeHeklaOntakeL1.s.sol deleted file mode 100644 index 0f9cdb67645..00000000000 --- a/packages/protocol/script/layer1/hekla/UpgradeHeklaOntakeL1.s.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; -import "src/layer1/hekla/HeklaInbox.sol"; -import "src/shared/bridge/Bridge.sol"; -import "src/layer1/provers/ProverSet.sol"; -import "script/BaseScript.sol"; - -contract UpgradeHeklaOntakeL1 is BaseScript { - function run() external broadcast { - address signalService = vm.envAddress("SIGNAL_SERVICE"); - address quotaManager = vm.envAddress("QUOTA_MANAGER"); - // Taiko - UUPSUpgradeable(0x79C9109b764609df928d16fC4a91e9081F7e87DB).upgradeTo( - address(new HeklaInbox(address(resolver))) - ); - // Bridge - UUPSUpgradeable(0xA098b76a3Dd499D3F6D58D8AcCaFC8efBFd06807).upgradeTo( - address(new Bridge(address(resolver), signalService, quotaManager)) - ); - // Rollup address manager - UUPSUpgradeable(0x1F027871F286Cf4B7F898B21298E7B3e090a8403).upgradeTo( - address(new DefaultResolver()) - ); - // Shared address manager - UUPSUpgradeable(0x7D3338FD5e654CAC5B10028088624CA1D64e74f7).upgradeTo( - address(new DefaultResolver()) - ); - // Prover set - UUPSUpgradeable(0xD3f681bD6B49887A48cC9C9953720903967E9DC0).upgradeTo( - address(new ProverSet(address(resolver))) - ); - UUPSUpgradeable(0x335103c4fa2F55451975082136F1478eCFeB84B9).upgradeTo( - address(new ProverSet(address(resolver))) - ); - } -} diff --git a/packages/protocol/script/layer1/hekla/UpgradeHeklaOntakeL2.s.sol b/packages/protocol/script/layer1/hekla/UpgradeHeklaOntakeL2.s.sol deleted file mode 100644 index 4c9117977a1..00000000000 --- a/packages/protocol/script/layer1/hekla/UpgradeHeklaOntakeL2.s.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; -import "src/shared/bridge/Bridge.sol"; -import "test/shared/thirdparty/Multicall3.sol"; -import "src/layer2/DelegateOwner.sol"; -import "script/BaseScript.sol"; - -contract UpgradeHeklaOntakeL2 is BaseScript { - address public delegateOwner = 0x95F6077C7786a58FA070D98043b16DF2B1593D2b; - address public multicall3 = 0xcA11bde05977b3631167028862bE2a173976CA11; - - address public newHeklaTaikoL2 = vm.envAddress("NEW_HEKLA_TAIKO_L2"); - address public newBridge = vm.envAddress("NEW_BRIDGE"); - address public newDefaultResolver = vm.envAddress("NEW_ADDRESS_MANAGER"); - address public newBridgedERC20 = vm.envAddress("NEW_BRIDGED_ERC20"); - - function run() external broadcast { - Multicall3.Call3[] memory calls = new Multicall3.Call3[](5); - // TaikoL2 - calls[0].target = 0x1670090000000000000000000000000000010001; - calls[0].allowFailure = false; - calls[0].callData = abi.encodeCall(UUPSUpgradeable.upgradeTo, (newHeklaTaikoL2)); - // Bridge - calls[1].target = 0x1670090000000000000000000000000000000001; - calls[1].allowFailure = false; - calls[1].callData = abi.encodeCall(UUPSUpgradeable.upgradeTo, (newBridge)); - // Rollup address manager - calls[2].target = 0x1670090000000000000000000000000000010002; - calls[2].allowFailure = false; - calls[2].callData = abi.encodeCall(UUPSUpgradeable.upgradeTo, (newDefaultResolver)); - // Shared address manager - calls[3].target = 0x1670090000000000000000000000000000000006; - calls[3].allowFailure = false; - calls[3].callData = abi.encodeCall(UUPSUpgradeable.upgradeTo, (newDefaultResolver)); - // Register Bridged ERC20 - calls[4].target = 0x1670090000000000000000000000000000000006; - calls[4].allowFailure = false; - calls[4].callData = abi.encodeCall( - DefaultResolver.registerAddress, (167_009, bytes32("bridged_erc20"), newBridgedERC20) - ); - - DelegateOwner.Call memory dcall = DelegateOwner.Call({ - txId: 0, - target: multicall3, - isDelegateCall: true, - txdata: abi.encodeCall(Multicall3.aggregate3, (calls)) - }); - - IBridge.Message memory message = IBridge.Message({ - id: 0, - fee: 0, - gasLimit: 3_000_000, - from: msg.sender, - srcChainId: 17_000, - srcOwner: msg.sender, - destChainId: 167_009, - destOwner: delegateOwner, - to: delegateOwner, - value: 0, - data: abi.encodeCall(DelegateOwner.onMessageInvocation, abi.encode(dcall)) - }); - - IBridge(0xA098b76a3Dd499D3F6D58D8AcCaFC8efBFd06807).sendMessage(message); - } -} diff --git a/packages/protocol/script/layer1/mainnet/DeployProverSet.s.sol b/packages/protocol/script/layer1/mainnet/DeployProverSet.s.sol index 956de521751..bfecadffe13 100644 --- a/packages/protocol/script/layer1/mainnet/DeployProverSet.s.sol +++ b/packages/protocol/script/layer1/mainnet/DeployProverSet.s.sol @@ -8,11 +8,19 @@ contract DeployProverSet is BaseScript { function run() external broadcast { address owner = vm.envOr("OWNER", msg.sender); address admin = vm.envOr("ADMIN", msg.sender); - address impl = vm.envOr("PROVER_SET_IMPL", address(new ProverSet(address(resolver)))); + + address taikoToken = vm.envAddress("TAIKO_TOKEN"); + address entrypoint = vm.envAddress("ENTRYPOINT"); + address inbox = vm.envAddress("INBOX"); require(owner != address(0), "OWNER not set"); require(admin != address(0), "ADMIN not set"); + address impl = vm.envOr( + "PROVER_SET_IMPL", + address(new ProverSet(address(resolver), inbox, taikoToken, entrypoint)) + ); + deploy({ name: "", impl: impl, data: abi.encodeCall(ProverSetBase.init, (owner, admin)) }); } } diff --git a/packages/protocol/script/layer1/preconf/DeployPreconfContracts.s.sol b/packages/protocol/script/layer1/preconf/DeployPreconfContracts.s.sol index ad46d7e46f4..1e2b53d2656 100644 --- a/packages/protocol/script/layer1/preconf/DeployPreconfContracts.s.sol +++ b/packages/protocol/script/layer1/preconf/DeployPreconfContracts.s.sol @@ -32,7 +32,7 @@ contract DeployPreconfContracts is BaseScript { // Deploy PreconfRouter deploy( - LibStrings.B_PRECONF_ROUTER, + "preconf_router", address(new PreconfRouter(taikoWrapper, preconfWhitelist)), abi.encodeCall(PreconfRouter.init, (contractOwner)) ); diff --git a/packages/protocol/test/genesis/GenerateGenesis.g.sol b/packages/protocol/test/genesis/GenerateGenesis.g.sol index 444649d75ab..99ff6096f5c 100644 --- a/packages/protocol/test/genesis/GenerateGenesis.g.sol +++ b/packages/protocol/test/genesis/GenerateGenesis.g.sol @@ -9,6 +9,9 @@ import "src/shared/bridge/Bridge.sol"; import "src/shared/tokenvault/ERC1155Vault.sol"; import "src/shared/tokenvault/ERC20Vault.sol"; import "src/shared/tokenvault/ERC721Vault.sol"; +import "src/shared/tokenvault/BridgedERC20.sol"; +import "src/shared/tokenvault/BridgedERC721.sol"; +import "src/shared/tokenvault/BridgedERC1155.sol"; import "src/shared/signal/SignalService.sol"; import "src/layer2/based/TaikoAnchor.sol"; import "../shared/helpers/RegularERC20.sol"; @@ -111,11 +114,21 @@ contract TestGenerateGenesis is Test { assertEq(contractOwner, taikoAnchorProxy.owner()); assertEq(l1ChainId, taikoAnchorProxy.l1ChainId()); assertEq(uint64(pacayaForkHeight), taikoAnchorProxy.pacayaForkHeight()); + assertEq( + getPredeployedContractAddress("SignalService"), + address(taikoAnchorProxy.signalService()) + ); vm.startPrank(taikoAnchorProxy.owner()); taikoAnchorProxy.upgradeTo( - address(new TaikoAnchor(getPredeployedContractAddress("RollupResolver"), 0)) + address( + new TaikoAnchor( + getPredeployedContractAddress("RollupResolver"), + getPredeployedContractAddress("SignalService"), + uint64(pacayaForkHeight) + ) + ) ); vm.stopPrank(); @@ -153,6 +166,10 @@ contract TestGenerateGenesis is Test { ); assertEq(bridgeProxy.paused(), false); + assertEq(address(0), address(bridgeProxy.quotaManager())); + assertEq( + getPredeployedContractAddress("SignalService"), address(bridgeProxy.signalService()) + ); vm.startPrank(contractOwner); bridgeProxy.pause(); @@ -179,11 +196,41 @@ contract TestGenerateGenesis is Test { bridgeProxy.unpause(); assertEq(bridgeProxy.paused(), false); - bridgeProxy.upgradeTo(address(new Bridge(getPredeployedContractAddress("SharedResolver")))); + bridgeProxy.upgradeTo( + address( + new Bridge( + getPredeployedContractAddress("SharedResolver"), + address(0), + getPredeployedContractAddress("SignalService") + ) + ) + ); vm.stopPrank(); } + function testBridgedERC20() public view { + address bridgedERC20 = getPredeployedContractAddress("BridgedERC20Impl"); + assertEq( + getPredeployedContractAddress("ERC20Vault"), BridgedERC20(bridgedERC20).erc20Vault() + ); + } + + function testBridgedERC721() public view { + address bridgedERC721 = getPredeployedContractAddress("BridgedERC721Impl"); + assertEq( + getPredeployedContractAddress("ERC721Vault"), BridgedERC721(bridgedERC721).erc721Vault() + ); + } + + function testBridgedERC1155() public view { + address bridgedERC1155 = getPredeployedContractAddress("BridgedERC1155Impl"); + assertEq( + getPredeployedContractAddress("ERC1155Vault"), + BridgedERC1155(bridgedERC1155).erc1155Vault() + ); + } + function testSingletonERC20Vault() public { address erc20VaultAddress = getPredeployedContractAddress("ERC20Vault"); address bridgeAddress = getPredeployedContractAddress("Bridge"); @@ -208,7 +255,7 @@ contract TestGenerateGenesis is Test { vm.stopPrank(); } - function testSingletonERC721Vault() public { + function testERC721Vault() public { address erc721VaultAddress = getPredeployedContractAddress("ERC721Vault"); address bridgeAddress = getPredeployedContractAddress("Bridge"); @@ -232,7 +279,7 @@ contract TestGenerateGenesis is Test { vm.stopPrank(); } - function testSingletonERC1155Vault() public { + function testERC1155Vault() public { address erc1155VaultProxyAddress = getPredeployedContractAddress("ERC1155Vault"); address bridgeProxyAddress = getPredeployedContractAddress("Bridge"); @@ -247,8 +294,6 @@ contract TestGenerateGenesis is Test { addressManager.registerAddress(1, "erc1155_vault", erc1155VaultProxyAddress); vm.stopPrank(); - // address erc1155VaultAddress = getPredeployedContractAddress("ERC1155VaultImpl"); - vm.startPrank(erc1155VaultProxy.owner()); erc1155VaultProxy.upgradeTo( @@ -258,7 +303,7 @@ contract TestGenerateGenesis is Test { vm.stopPrank(); } - function testSingletonSignalService() public { + function testSignalService() public { SignalService signalServiceProxy = SignalService(getPredeployedContractAddress("SignalService")); @@ -268,9 +313,6 @@ contract TestGenerateGenesis is Test { vm.startPrank(contractOwner); - // SignalService signalService = - // SignalService(payable(getPredeployedContractAddress("SignalServiceImpl"))); - signalServiceProxy.upgradeTo( address(new SignalService(getPredeployedContractAddress("SharedResolver"))) ); @@ -307,7 +349,7 @@ contract TestGenerateGenesis is Test { function checkProxyImplementation(string memory proxyName, address owner) private { vm.startPrank(owner); - // address contractAddress = getPredeployedContractAddress(contractName); + address proxyAddress = getPredeployedContractAddress(proxyName); EssentialContract proxy = EssentialContract(payable(proxyAddress)); diff --git a/packages/protocol/test/genesis/generate/taikoAnchor.ts b/packages/protocol/test/genesis/generate/taikoAnchor.ts index 1a05fb869a3..a5a3146ba53 100644 --- a/packages/protocol/test/genesis/generate/taikoAnchor.ts +++ b/packages/protocol/test/genesis/generate/taikoAnchor.ts @@ -187,17 +187,33 @@ async function generateContractConfigs( const addressMap: any = {}; - const essentialContractReferencesMap: any = getImmutableReferences( + const essentialContractReferencesMap: any = getImmutableReference( "EssentialContract", - "__resolver", + ["__resolver"], ); - const uupsImmutableReferencesMap: any = getImmutableReferences( + const uupsImmutableReferencesMap: any = getImmutableReference( "UUPSUpgradeable", - "__self", + ["__self"], ); - const taikoAnchorReferencesMap: any = getImmutableReferences( - "TaikoAnchor", + const taikoAnchorReferencesMap: any = getImmutableReference("TaikoAnchor", [ "pacayaForkHeight", + "signalService", + ]); + const bridgeReferencesMap: any = getImmutableReference("Bridge", [ + "signalService", + "quotaManager", + ]); + const bridgedERC20ReferencesMap: any = getImmutableReference( + "BridgedERC20", + ["erc20Vault"], + ); + const bridgedERC721ReferencesMap: any = getImmutableReference( + "BridgedERC721", + ["erc721Vault"], + ); + const bridgedERC1155ReferencesMap: any = getImmutableReference( + "BridgedERC1155", + ["erc1155Vault"], ); for (const [contractName, artifact] of Object.entries(contractArtifacts)) { @@ -226,9 +242,9 @@ async function generateContractConfigs( // Shared Contracts SharedResolverImpl: { address: addressMap.SharedResolverImpl, - deployedBytecode: replaceImmutableValues( + deployedBytecode: replaceImmutableValue( contractArtifacts.SharedResolverImpl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, + uupsImmutableReferencesMap.__self.id, ethers.utils.hexZeroPad(addressMap.SharedResolverImpl, 32), ).deployedBytecode.object, variables: { @@ -289,15 +305,29 @@ async function generateContractConfigs( BridgeImpl: { address: addressMap.BridgeImpl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.BridgeImpl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad(addressMap.BridgeImpl, 32), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + replaceImmutableValues(contractArtifacts.BridgeImpl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( + addressMap.BridgeImpl, + 32, + ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + { + id: bridgeReferencesMap.signalService.id, + value: ethers.utils.hexZeroPad( + addressMap.SignalService, + 32, + ), + }, + ]), addressMap, ), variables: { @@ -325,15 +355,22 @@ async function generateContractConfigs( ERC20VaultImpl: { address: addressMap.ERC20VaultImpl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.ERC20VaultImpl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad(addressMap.ERC20VaultImpl, 32), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + replaceImmutableValues(contractArtifacts.ERC20VaultImpl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( + addressMap.ERC20VaultImpl, + 32, + ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + ]), addressMap, ), variables: { @@ -362,15 +399,22 @@ async function generateContractConfigs( ERC721VaultImpl: { address: addressMap.ERC721VaultImpl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.ERC721VaultImpl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad(addressMap.ERC721VaultImpl, 32), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + replaceImmutableValues(contractArtifacts.ERC721VaultImpl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( + addressMap.ERC721VaultImpl, + 32, + ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + ]), addressMap, ), variables: { @@ -399,18 +443,22 @@ async function generateContractConfigs( ERC1155VaultImpl: { address: addressMap.ERC1155VaultImpl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.ERC1155VaultImpl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad( + replaceImmutableValues(contractArtifacts.ERC1155VaultImpl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( addressMap.ERC1155VaultImpl, 32, ), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + ]), addressMap, ), variables: { @@ -439,72 +487,109 @@ async function generateContractConfigs( BridgedERC20: { address: addressMap.BridgedERC20Impl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.BridgedERC20Impl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad( + replaceImmutableValues(contractArtifacts.BridgedERC20Impl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( addressMap.BridgedERC20Impl, 32, ), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + { + id: bridgedERC20ReferencesMap.erc20Vault.id, + value: ethers.utils.hexZeroPad( + addressMap.ERC20Vault, + 32, + ), + }, + ]), addressMap, ), }, BridgedERC721: { address: addressMap.BridgedERC721Impl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.BridgedERC721Impl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad( + replaceImmutableValues(contractArtifacts.BridgedERC721Impl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( addressMap.BridgedERC721Impl, 32, ), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + { + id: bridgedERC721ReferencesMap.erc721Vault.id, + value: ethers.utils.hexZeroPad( + addressMap.ERC721Vault, + 32, + ), + }, + ]), addressMap, ), }, BridgedERC1155: { address: addressMap.BridgedERC1155Impl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.BridgedERC1155Impl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad( + replaceImmutableValues(contractArtifacts.BridgedERC1155Impl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( addressMap.BridgedERC1155Impl, 32, ), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + { + id: bridgedERC1155ReferencesMap.erc1155Vault.id, + value: ethers.utils.hexZeroPad( + addressMap.ERC1155Vault, + 32, + ), + }, + ]), addressMap, ), }, SignalServiceImpl: { address: addressMap.SignalServiceImpl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.SignalServiceImpl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad( + replaceImmutableValues(contractArtifacts.SignalServiceImpl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( addressMap.SignalServiceImpl, 32, ), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.SharedResolver, 32), - ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + ]), addressMap, ), variables: { @@ -537,22 +622,36 @@ async function generateContractConfigs( TaikoAnchorImpl: { address: addressMap.TaikoAnchorImpl, deployedBytecode: linkContractLibs( - replaceImmutableValues( - replaceImmutableValues( - replaceImmutableValues( - contractArtifacts.TaikoAnchorImpl, - taikoAnchorReferencesMap.TaikoAnchor.id, - ethers.utils.hexZeroPad( - ethers.utils.hexlify(pacayaForkHeight), - 32, - ), + replaceImmutableValues(contractArtifacts.TaikoAnchorImpl, [ + { + id: uupsImmutableReferencesMap.__self.id, + value: ethers.utils.hexZeroPad( + addressMap.TaikoAnchorImpl, + 32, ), - uupsImmutableReferencesMap.UUPSUpgradeable.id, - ethers.utils.hexZeroPad(addressMap.TaikoAnchorImpl, 32), - ), - essentialContractReferencesMap.EssentialContract.id, - ethers.utils.hexZeroPad(addressMap.RollupResolver, 32), - ), + }, + { + id: essentialContractReferencesMap.__resolver.id, + value: ethers.utils.hexZeroPad( + addressMap.SharedResolver, + 32, + ), + }, + { + id: taikoAnchorReferencesMap.pacayaForkHeight.id, + value: ethers.utils.hexZeroPad( + ethers.utils.hexlify(pacayaForkHeight), + 32, + ), + }, + { + id: taikoAnchorReferencesMap.signalService.id, + value: ethers.utils.hexZeroPad( + addressMap.SignalService, + 32, + ), + }, + ]), addressMap, ), variables: { @@ -597,9 +696,9 @@ async function generateContractConfigs( }, RollupResolverImpl: { address: addressMap.RollupResolverImpl, - deployedBytecode: replaceImmutableValues( + deployedBytecode: replaceImmutableValue( contractArtifacts.RollupResolverImpl, - uupsImmutableReferencesMap.UUPSUpgradeable.id, + uupsImmutableReferencesMap.__self.id, ethers.utils.hexZeroPad(addressMap.RollupResolverImpl, 32), ).deployedBytecode.object, variables: { @@ -688,9 +787,9 @@ function getLinkLibs(artifact: any, linkRefs: any, addressMap: any) { return result; } -function getImmutableReferences( +function getImmutableReference( contractName: string, - immutableValueName: string, + immutableValueNames: Array, ) { const references: any = {}; const artifact = require( @@ -700,20 +799,30 @@ function getImmutableReferences( for (const node of artifact.ast.nodes) { if (node.nodeType !== "ContractDefinition") continue; - for (const subNode of node.nodes) { - if (subNode.name !== immutableValueName) continue; - references[`${contractName}`] = { - name: immutableValueName, - id: subNode.id, - }; - break; + for (const immutableValueName of immutableValueNames) { + for (const subNode of node.nodes) { + if (subNode.name !== immutableValueName) continue; + references[immutableValueName] = { + name: immutableValueName, + id: subNode.id, + }; + break; + } } } return references; } -function replaceImmutableValues(artifact: any, id: any, value: string): any { +function replaceImmutableValues(artifact: any, maps: Array): any { + for (let i = 0; i < maps.length; i++) { + artifact = replaceImmutableValue(artifact, maps[i].id, maps[i].value); + } + + return artifact; +} + +function replaceImmutableValue(artifact: any, id: any, value: string): any { const offsets = artifact.deployedBytecode.immutableReferences[`${id}`]; let deployedBytecodeWithoutPrefix = artifact.deployedBytecode.object.substring(2); diff --git a/packages/protocol/test/layer1/Layer1Test.sol b/packages/protocol/test/layer1/Layer1Test.sol index 08ca4f48389..6fa238cdfed 100644 --- a/packages/protocol/test/layer1/Layer1Test.sol +++ b/packages/protocol/test/layer1/Layer1Test.sol @@ -16,7 +16,14 @@ import "test/shared/CommonTest.sol"; contract ConfigurableInbox is TaikoInbox { ITaikoInbox.Config private __config; - constructor(address _resolver) TaikoInbox(_resolver) { } + constructor( + address _wrapper, + address _verifier, + address _bondToken, + address _signalService + ) + TaikoInbox(_wrapper, _verifier, _bondToken, _signalService) + { } function initWithConfig( address _owner, @@ -50,6 +57,9 @@ contract ConfigurableInbox is TaikoInbox { abstract contract Layer1Test is CommonTest { function deployInbox( bytes32 _genesisBlockHash, + address _verifier, + address _bondToken, + address _signalService, ITaikoInbox.Config memory _config ) internal @@ -58,7 +68,7 @@ abstract contract Layer1Test is CommonTest { return TaikoInbox( deploy({ name: "taiko", - impl: address(new ConfigurableInbox(address(resolver))), + impl: address(new ConfigurableInbox(address(0), _verifier, _bondToken, _signalService)), data: abi.encodeCall( ConfigurableInbox.initWithConfig, (address(0), _genesisBlockHash, _config) ) diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 434c0e1e5a7..a8a9eade600 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -37,15 +37,21 @@ abstract contract InboxTestBase is Layer1Test { __blocksPerBatch = 1; - inbox = deployInbox(correctBlockhash(0), pacayaConfig()); - signalService = deploySignalService(address(new SignalService(address(resolver)))); - signalService.authorize(address(inbox), true); - resolver.registerAddress( - block.chainid, "proof_verifier", address(new Verifier_ToggleStub()) + address verifierAddr = address(new Verifier_ToggleStub()); + resolver.registerAddress(block.chainid, "proof_verifier", verifierAddr); + + inbox = deployInbox( + correctBlockhash(0), + verifierAddr, + address(bondToken), + address(signalService), + pacayaConfig() ); + signalService.authorize(address(inbox), true); + mineOneBlockAndWrap(12 seconds); } diff --git a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol index 4ddcb55aa3a..a787263e43c 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol @@ -32,8 +32,8 @@ contract InboxTest_BondMechanics is InboxTestBase { } function setUpOnEthereum() internal override { - super.setUpOnEthereum(); bondToken = deployBondToken(); + super.setUpOnEthereum(); } function test_inbox_bonds_debit_and_credit_proved_by_proposer_in_proving_window() external { diff --git a/packages/protocol/test/layer1/based/InboxTest_BondToken.t.sol b/packages/protocol/test/layer1/based/InboxTest_BondToken.t.sol index c9ea433e63e..dd3955c9d57 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondToken.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondToken.t.sol @@ -32,8 +32,8 @@ contract InboxTest_BondToken is InboxTestBase { } function setUpOnEthereum() internal override { - super.setUpOnEthereum(); bondToken = deployBondToken(); + super.setUpOnEthereum(); } function test_inbox_deposit_withdraw() external { diff --git a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol index e0089afb65d..e86fa86cdad 100644 --- a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol @@ -32,8 +32,8 @@ contract InboxTest_CalldataForTxList is InboxTestBase { } function setUpOnEthereum() internal override { - super.setUpOnEthereum(); bondToken = deployBondToken(); + super.setUpOnEthereum(); } function test_calldata_used_for_txlist_da() external { diff --git a/packages/protocol/test/layer1/based/InboxTest_Cooldown.t.sol b/packages/protocol/test/layer1/based/InboxTest_Cooldown.t.sol index 442bc8bc019..c807340ab44 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Cooldown.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Cooldown.t.sol @@ -31,8 +31,8 @@ contract InboxTest_Cooldownis is InboxTestBase { } function setUpOnEthereum() internal override { - super.setUpOnEthereum(); bondToken = deployBondToken(); + super.setUpOnEthereum(); } function test_inbox_batches_cannot_verify_inside_cooldown_window() diff --git a/packages/protocol/test/layer1/based/InboxTest_Params.t.sol b/packages/protocol/test/layer1/based/InboxTest_Params.t.sol index ce808300389..e33b9297b97 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Params.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Params.t.sol @@ -31,8 +31,8 @@ contract InboxTest_Params is InboxTestBase { } function setUpOnEthereum() internal override { - super.setUpOnEthereum(); bondToken = deployBondToken(); + super.setUpOnEthereum(); } function test_validateParams_defaults_when_anchorBlockId_is_zero() external transactBy(Alice) { diff --git a/packages/protocol/test/layer1/based/InboxTest_ProposeAndProve.t.sol b/packages/protocol/test/layer1/based/InboxTest_ProposeAndProve.t.sol index 816785b0327..46a648c97c9 100644 --- a/packages/protocol/test/layer1/based/InboxTest_ProposeAndProve.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_ProposeAndProve.t.sol @@ -31,8 +31,8 @@ contract InboxTest_ProposeAndProve is InboxTestBase { } function setUpOnEthereum() internal override { - super.setUpOnEthereum(); bondToken = deployBondToken(); + super.setUpOnEthereum(); } function test_inbox_query_right_after_genesis_batch() external view { @@ -522,18 +522,6 @@ contract InboxTest_ProposeAndProve is InboxTestBase { address operator = Bob; resolver.registerAddress(block.chainid, "inbox_operator", operator); vm.stopPrank(); - - vm.startPrank(Alice); - params.proposer = operator; - vm.expectRevert(ITaikoInbox.NotInboxWrapper.selector); - inbox.proposeBatch(abi.encode(params), "txList"); - vm.stopPrank(); - - vm.startPrank(operator); - params.proposer = address(0); - vm.expectRevert(ITaikoInbox.CustomProposerMissing.selector); - inbox.proposeBatch(abi.encode(params), "txList"); - vm.stopPrank(); } function test_inbox_measure_gas_used() diff --git a/packages/protocol/test/layer1/based/InboxTest_StopBatch.t.sol b/packages/protocol/test/layer1/based/InboxTest_StopBatch.t.sol index afa8ce4e970..9b6e9fac2d8 100644 --- a/packages/protocol/test/layer1/based/InboxTest_StopBatch.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_StopBatch.t.sol @@ -31,8 +31,8 @@ contract InboxTest_StopBatch is InboxTestBase { } function setUpOnEthereum() internal override { - super.setUpOnEthereum(); bondToken = deployBondToken(); + super.setUpOnEthereum(); } function test_inbox_num_batches_verified() diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock.t.sol index cbe048a242a..a5379c09df4 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock.t.sol @@ -44,7 +44,10 @@ contract TestTokenUnlock is Layer1Test { register("bond_token", address(taikoToken)); register("taiko_token", address(taikoToken)); register("taiko", taikoL1); - register("prover_set", address(new ProverSet(address(resolver)))); + register( + "prover_set", + address(new ProverSet(address(resolver), taikoL1, address(taikoToken), taikoL1)) + ); target = TokenUnlock( deploy({ diff --git a/packages/protocol/test/shared/tokenvault/ERC1155Vault.t.sol b/packages/protocol/test/shared/tokenvault/ERC1155Vault.t.sol index 3e3e088494b..ecaf18f5bb7 100644 --- a/packages/protocol/test/shared/tokenvault/ERC1155Vault.t.sol +++ b/packages/protocol/test/shared/tokenvault/ERC1155Vault.t.sol @@ -28,7 +28,7 @@ contract TestERC1155Vault is CommonTest { ); eVault = deployERC1155Vault(); - register("bridged_erc1155", address(new BridgedERC1155(address(resolver)))); + register("bridged_erc1155", address(new BridgedERC1155(address(eVault)))); vm.deal(address(eBridge), 100 ether); vm.deal(Alice, 100 ether); @@ -43,7 +43,7 @@ contract TestERC1155Vault is CommonTest { ); register("bridge", address(tBridge)); - register("bridged_erc1155", address(new BridgedERC1155(address(resolver)))); + register("bridged_erc1155", address(new BridgedERC1155(address(tVault)))); vm.deal(address(tBridge), 100 ether); } diff --git a/packages/protocol/test/shared/tokenvault/ERC721Vault.t.sol b/packages/protocol/test/shared/tokenvault/ERC721Vault.t.sol index d298badbc37..2f99532cb3b 100644 --- a/packages/protocol/test/shared/tokenvault/ERC721Vault.t.sol +++ b/packages/protocol/test/shared/tokenvault/ERC721Vault.t.sol @@ -24,7 +24,7 @@ contract TestERC721Vault is CommonTest { eBridge = deployBridge(address(new Bridge(address(resolver), address(ss), quotaManager))); eVault = deployERC721Vault(); - register("bridged_erc721", address(new BridgedERC721(address(resolver)))); + register("bridged_erc721", address(new BridgedERC721(address(eVault)))); vm.deal(Alice, 100 ether); vm.deal(Bob, 100 ether); @@ -36,7 +36,7 @@ contract TestERC721Vault is CommonTest { tBridge = new PrankDestBridge(tVault); register("bridge", address(tBridge)); - register("bridged_erc721", address(new BridgedERC721(address(resolver)))); + register("bridged_erc721", address(new BridgedERC721(address(tVault)))); vm.deal(address(tBridge), 100 ether); }