diff --git a/lib/automata-dcap-attestation b/lib/automata-dcap-attestation index ad785ced..913c0f0e 160000 --- a/lib/automata-dcap-attestation +++ b/lib/automata-dcap-attestation @@ -1 +1 @@ -Subproject commit ad785cedd1bf93d3142f4a377e7e603129311037 +Subproject commit 913c0f0e97d0976b9c317b591ed83ac319d05c3a diff --git a/lib/forge-std b/lib/forge-std index 2b59872e..83c5d212 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 2b59872eee0b8088ddcade39fe8c041e17bb79c0 +Subproject commit 83c5d212a01f8950727da4095cdfe2654baccb5b diff --git a/scripts/deployEspressoTEEVerifier.ts b/scripts/deployEspressoTEEVerifier.ts index 661d6055..e8798408 100644 --- a/scripts/deployEspressoTEEVerifier.ts +++ b/scripts/deployEspressoTEEVerifier.ts @@ -5,15 +5,25 @@ import { deployContract } from './deploymentUtils' async function main() { const [deployer] = await ethers.getSigners() - const pccsRouterAddress = process.env.PCCS_ROUTER_ADDRESS as string - if (!pccsRouterAddress) { - throw new Error('PCCS_ROUTER_ADDRESS not set') + const v3QuoteVerifier = process.env.V3_QUOTE_VERIFIER_ADDRESS + if (!v3QuoteVerifier) { + throw new Error('V3_QUOTE_VERIFIER_ADDRESS not set') + } + + const mrEnclave = process.env.MR_ENCLAVE + if (!mrEnclave) { + throw new Error('MR_ENCLAVE not set') + } + + const mrSigner = process.env.MR_SIGNER + if (!mrSigner) { + throw new Error('MR_SIGNER not set') } const esperssoTEEVerifier = await deployContract( 'EspressoTEEVerifier', deployer, - [pccsRouterAddress], + [mrEnclave, mrSigner, v3QuoteVerifier], true ) console.log( diff --git a/src/bridge/EspressoTEEVerifier.sol b/src/bridge/EspressoTEEVerifier.sol index b555dfcb..08dbc082 100644 --- a/src/bridge/EspressoTEEVerifier.sol +++ b/src/bridge/EspressoTEEVerifier.sol @@ -14,6 +14,12 @@ import { ENCLAVE_REPORT_LENGTH } from "@automata-network/dcap-attestation/contracts/types/Constants.sol"; import {EnclaveReport} from "@automata-network/dcap-attestation/contracts/types/V3Structs.sol"; +import { + V3QuoteVerifier +} from "@automata-network/dcap-attestation/contracts/verifiers/V3QuoteVerifier.sol"; +import {BytesUtils} from "@automata-network/dcap-attestation/contracts/utils/BytesUtils.sol"; +import {Ownable} from "solady/auth/Ownable.sol"; + /** * * @title Verifies quotes from the TEE and attests on-chain @@ -21,28 +27,45 @@ import {EnclaveReport} from "@automata-network/dcap-attestation/contracts/types/ * to verify the quote. Along with some additional verification logic. */ -contract EspressoTEEVerifier is V3QuoteVerifier { - constructor(address _router) V3QuoteVerifier(_router) {} +contract EspressoTEEVerifier is Ownable { + using BytesUtils for bytes; + // TODO: add comments + V3QuoteVerifier public quoteVerifier; + bytes32 public mrEnclave; + bytes32 public mrSigner; + + constructor(bytes32 _mrEnclave, bytes32 _mrSigner, address _quoteVerifier) { + quoteVerifier = V3QuoteVerifier(_quoteVerifier); + mrEnclave = _mrEnclave; + mrSigner = _mrSigner; + _initializeOwner(msg.sender); + } - /** + /* @notice Verify a quote from the TEE and attest on-chain @param rawQuote The quote from the TEE - @return success True if the quote was verified and attested on-chain - */ - function verify(bytes calldata rawQuote) external view returns (bool success) { + @param reportDataHash The hash of the report data + @return success True if the quote was verified and attested on-chain, false otherwise + */ + function verify( + bytes calldata rawQuote, + bytes32 reportDataHash + ) external view returns (bool success) { // Parse the header - Header memory header = _parseQuoteHeader(rawQuote); + Header memory header = parseQuoteHeader(rawQuote); + // Currently only version 3 is supported if (header.version != 3) { return false; } - (success, ) = this.verifyQuote(header, rawQuote); + // Verify the quote + (success, ) = quoteVerifier.verifyQuote(header, rawQuote); if (!success) { return false; } - // Parse enclave quote + // Parse enclave quote uint256 offset = HEADER_LENGTH + ENCLAVE_REPORT_LENGTH; EnclaveReport memory localReport; (success, localReport) = parseEnclaveReport(rawQuote[HEADER_LENGTH:offset]); @@ -50,14 +73,24 @@ contract EspressoTEEVerifier is V3QuoteVerifier { return false; } - return true; + // Check that mrEnclave and mrSigner match + if (localReport.mrEnclave != mrEnclave || localReport.mrSigner != mrSigner) { + return false; + } + + if (reportDataHash != bytes32(localReport.reportData.substring(0, 32))) { + return false; + } - // TODO: Use the parsed enclave report (localReport) to do other verifications + return true; } - function _parseQuoteHeader( - bytes calldata rawQuote - ) private pure returns (Header memory header) { + /* + @notice Parses the header from the quote + @param rawQuote The raw quote in bytes + @return header The parsed header + */ + function parseQuoteHeader(bytes calldata rawQuote) public pure returns (Header memory header) { bytes2 attestationKeyType = bytes2(rawQuote[2:4]); bytes2 qeSvn = bytes2(rawQuote[8:10]); bytes2 pceSvn = bytes2(rawQuote[10:12]); @@ -73,4 +106,44 @@ contract EspressoTEEVerifier is V3QuoteVerifier { userData: bytes20(rawQuote[28:48]) }); } + + /* + @notice Parses the enclave report from the quote + @param rawEnclaveReport The raw enclave report from the quote in bytes + @return success True if the enclave report was parsed successfully + @return enclaveReport The parsed enclave report + */ + + function parseEnclaveReport( + bytes memory rawEnclaveReport + ) public pure returns (bool success, EnclaveReport memory enclaveReport) { + if (rawEnclaveReport.length != ENCLAVE_REPORT_LENGTH) { + return (false, enclaveReport); + } + enclaveReport.cpuSvn = bytes16(rawEnclaveReport.substring(0, 16)); + enclaveReport.miscSelect = bytes4(rawEnclaveReport.substring(16, 4)); + enclaveReport.reserved1 = bytes28(rawEnclaveReport.substring(20, 28)); + enclaveReport.attributes = bytes16(rawEnclaveReport.substring(48, 16)); + enclaveReport.mrEnclave = bytes32(rawEnclaveReport.substring(64, 32)); + enclaveReport.reserved2 = bytes32(rawEnclaveReport.substring(96, 32)); + enclaveReport.mrSigner = bytes32(rawEnclaveReport.substring(128, 32)); + enclaveReport.reserved3 = rawEnclaveReport.substring(160, 96); + enclaveReport.isvProdId = uint16(BELE.leBytesToBeUint(rawEnclaveReport.substring(256, 2))); + enclaveReport.isvSvn = uint16(BELE.leBytesToBeUint(rawEnclaveReport.substring(258, 2))); + enclaveReport.reserved4 = rawEnclaveReport.substring(260, 60); + enclaveReport.reportData = rawEnclaveReport.substring(320, 64); + success = true; + } + + function setOwner(address newOwner) external onlyOwner { + _setOwner(newOwner); + } + + function setMrEnclave(bytes32 _mrEnclave) external onlyOwner { + mrEnclave = _mrEnclave; + } + + function setMrSigner(bytes32 _mrSigner) external onlyOwner { + mrSigner = _mrSigner; + } } diff --git a/src/bridge/SequencerInbox.sol b/src/bridge/SequencerInbox.sol index 09cc3aaf..754f0705 100644 --- a/src/bridge/SequencerInbox.sol +++ b/src/bridge/SequencerInbox.sol @@ -182,10 +182,7 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox __LEGACY_MAX_TIME_VARIATION.futureSeconds = 0; } - function initialize( - IBridge bridge_, - ISequencerInbox.MaxTimeVariation calldata maxTimeVariation_ - ) external onlyDelegated { + function initialize(IBridge, ISequencerInbox.MaxTimeVariation calldata) external onlyDelegated { revert Deprecated(); } @@ -373,7 +370,18 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox if (msg.sender != tx.origin) revert NotOrigin(); if (!isBatchPoster[msg.sender]) revert NotBatchPoster(); - bool success = espressoTEEVerifier.verify(quote); + // take keccak2256 hash of all the function arguments except the quote + bytes32 reportDataHash = keccak256( + abi.encodePacked( + sequenceNumber, + data, + afterDelayedMessagesRead, + address(gasRefunder), + prevMessageCount, + newMessageCount + ) + ); + bool success = espressoTEEVerifier.verify(quote, reportDataHash); if (!success) { revert InvalidTEEAttestationQuote(); } @@ -481,12 +489,12 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox } function addSequencerL2Batch( - uint256 sequenceNumber, - bytes calldata data, - uint256 afterDelayedMessagesRead, + uint256, + bytes calldata, + uint256, IGasRefunder gasRefunder, - uint256 prevMessageCount, - uint256 newMessageCount + uint256, + uint256 ) external override refundsGas(gasRefunder, IReader4844(address(0))) { revert Deprecated(); } @@ -516,7 +524,18 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox // Only check the attestation quote if the batch has been posted by the // batch poster if (isBatchPoster[msg.sender]) { - bool success = espressoTEEVerifier.verify(quote); + // take keccak2256 hash of all the function arguments except the quote + bytes32 reportDataHash = keccak256( + abi.encodePacked( + sequenceNumber, + data, + afterDelayedMessagesRead, + address(gasRefunder), + prevMessageCount, + newMessageCount + ) + ); + bool success = espressoTEEVerifier.verify(quote, reportDataHash); if (!success) { revert InvalidTEEAttestationQuote(); } diff --git a/src/rollup/BridgeCreator.sol b/src/rollup/BridgeCreator.sol index b77996e9..48fe6293 100644 --- a/src/rollup/BridgeCreator.sol +++ b/src/rollup/BridgeCreator.sol @@ -80,10 +80,10 @@ contract BridgeCreator is Ownable { /// @dev Deprecated function createBridge( - address adminProxy, - address rollup, - address nativeToken, - ISequencerInbox.MaxTimeVariation calldata maxTimeVariation + address, + address, + address, + ISequencerInbox.MaxTimeVariation calldata ) external returns (BridgeContracts memory) { revert Deprecated(); } diff --git a/test/e2e/orbitChain.ts b/test/e2e/orbitChain.ts index c422c2a4..bb2aefdf 100644 --- a/test/e2e/orbitChain.ts +++ b/test/e2e/orbitChain.ts @@ -15,6 +15,7 @@ import { ERC20, ERC20Inbox__factory, ERC20__factory, + EspressoTEEVerifierMock__factory, EthVault__factory, IERC20Bridge__factory, IInbox__factory, @@ -631,404 +632,387 @@ describe('Orbit Chain', () => { ) }) - // TODO: Fill fix these in follow up PR's - - // it('can deploy deterministic factories to L2', async function () { - // const rollupCreator = RollupCreator__factory.connect( - // await _getRollupCreatorFromLogs(l1Provider), - // l1Provider - // ) - - // const deployHelper = DeployHelper__factory.connect( - // await rollupCreator.l2FactoriesDeployer(), - // l1Provider - // ) - - // const inbox = l2Network.ethBridge.inbox - // const maxFeePerGas = BigNumber.from('100000000') // 0.1 gwei - // let fee = await deployHelper.getDeploymentTotalCost(inbox, maxFeePerGas) - - // if (nativeToken) { - // const decimals = await nativeToken.decimals() - // if (decimals < 18) { - // // if token has less than 18 decimals we need to sum fee costs per each retryable, - // // as there could be rounding effect for each one of them - // fee = BigNumber.from(0) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.NICK_CREATE2_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.ERC2470_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.ZOLTU_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.ERC1820_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // } else { - // fee = await _scaleFrom18ToNative(fee) - // } - - // await ( - // await nativeToken.connect(userL1Wallet).transfer(inbox, fee) - // ).wait() - // } - - // // deploy factories - // const receipt = await ( - // await deployHelper - // .connect(userL1Wallet) - // .perform( - // inbox, - // nativeToken ? nativeToken.address : ethers.constants.AddressZero, - // maxFeePerGas, - // { value: nativeToken ? BigNumber.from(0) : fee } - // ) - // ).wait() - - // const l1TxReceipt = new L1TransactionReceipt(receipt) - // const messages = await l1TxReceipt.getL1ToL2Messages(l2Provider) - // const messageResults = await Promise.all( - // messages.map(message => message.waitForStatus()) - // ) - - // expect(messageResults[0].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) - // expect(messageResults[1].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) - // expect(messageResults[2].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) - // expect(messageResults[3].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) - - // const deployedFactories = [ - // '0x4e59b44847b379578588920ca78fbf26c0b4956c', - // '0xce0042B868300000d44A59004Da54A005ffdcf9f', - // '0x7A0D94F55792C434d74a40883C6ed8545E406D12', - // '0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24', - // ] - // deployedFactories.forEach(async factory => { - // expect((await l2Provider.getCode(factory)).length).to.be.gt( - // EMPTY_CODE_LENGTH - // ) - // }) - // }) - - // it('can deploy deterministic factories to L2 through RollupCreator', async function () { - // const rollupCreator = RollupCreator__factory.connect( - // await _getRollupCreatorFromLogs(l1Provider), - // l1Provider - // ) - - // const deployHelper = DeployHelper__factory.connect( - // await rollupCreator.l2FactoriesDeployer(), - // l1Provider - // ) - - // const inbox = l2Network.ethBridge.inbox - // const maxFeePerGas = BigNumber.from('100000000') // 0.1 gwei - // let fee = await deployHelper.getDeploymentTotalCost(inbox, maxFeePerGas) - // if (nativeToken) { - // const decimals = await nativeToken.decimals() - // if (decimals < 18) { - // // if token has less than 18 decimals we need to sum fee costs per each retryable, - // // as there could be rounding effect for each one of them - // fee = BigNumber.from(0) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.NICK_CREATE2_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.ERC2470_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.ZOLTU_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // fee = fee.add( - // await _scaleFrom18ToNative( - // ( - // await deployHelper.ERC1820_VALUE() - // ).add(maxFeePerGas.mul(BigNumber.from(21000))) - // ) - // ) - // } else { - // fee = await _scaleFrom18ToNative(fee) - // } - - // await ( - // await nativeToken - // .connect(userL1Wallet) - // .approve(rollupCreator.address, fee) - // ).wait() - // } - - // let userL1NativeAssetBalance: BigNumber - // if (nativeToken) { - // userL1NativeAssetBalance = await nativeToken.balanceOf( - // userL1Wallet.address - // ) - // } else { - // userL1NativeAssetBalance = await l1Provider.getBalance( - // userL1Wallet.address - // ) - // } - - // const batchPosters = [ethers.Wallet.createRandom().address] - // const batchPosterManager = ethers.Wallet.createRandom().address - // const teeAdmin = ethers.Wallet.createRandom().address - // const validators = [ethers.Wallet.createRandom().address] - // const maxDataSize = 104857 - // const nativeTokenAddress = nativeToken - // ? nativeToken.address - // : ethers.constants.AddressZero - // const deployFactoriesToL2 = true - // const maxFeePerGasForRetryables = BigNumber.from('100000000') // 0.1 gwei - // const espressoTEEVerifierFac = (await hardhatEthers.getContractFactory( - // 'EspressoTEEVerifierTest' - // )) as EspressoTEEVerifierTest__factory - // const espressoTEEVerifier = await espressoTEEVerifierFac.deploy() - // await espressoTEEVerifier.deployed() - // const transparentUpgradeableProxyFac = - // (await hardhatEthers.getContractFactory( - // 'TransparentUpgradeableProxy' - // )) as TransparentUpgradeableProxy__factory - - // const espressoTEEVerifierProxy = - // await transparentUpgradeableProxyFac.deploy( - // espressoTEEVerifier.address, - // teeAdmin, - // '0x' - // ) - // await espressoTEEVerifierProxy.deployed() - // await espressoTEEVerifierFac - // .attach(espressoTEEVerifierProxy.address) - // .connect(userL1Wallet) - - // /// deploy params - // const config = { - // confirmPeriodBlocks: ethers.BigNumber.from('150'), - // extraChallengeTimeBlocks: ethers.BigNumber.from('200'), - // stakeToken: ethers.constants.AddressZero, - // baseStake: ethers.utils.parseEther('1'), - // wasmModuleRoot: - // '0xda4e3ad5e7feacb817c21c8d0220da7650fe9051ece68a3f0b1c5d38bbb27b21', - // owner: '0x72f7EEedF02C522242a4D3Bdc8aE6A8583aD7c5e', - // loserStakeEscrow: ethers.constants.AddressZero, - // chainId: ethers.BigNumber.from('433333'), - // chainConfig: - // '{"chainId":433333,"homesteadBlock":0,"daoForkBlock":null,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":0,"berlinBlock":0,"londonBlock":0,"clique":{"period":0,"epoch":0},"arbitrum":{"EnableArbOS":true,"AllowDebugPrecompiles":false,"DataAvailabilityCommittee":false,"InitialArbOSVersion":10,"InitialChainOwner":"0x72f7EEedF02C522242a4D3Bdc8aE6A8583aD7c5e","GenesisBlockNum":0}}', - // genesisBlockNum: ethers.BigNumber.from('0'), - // sequencerInboxMaxTimeVariation: { - // delayBlocks: ethers.BigNumber.from('5760'), - // futureBlocks: ethers.BigNumber.from('12'), - // delaySeconds: ethers.BigNumber.from('86400'), - // futureSeconds: ethers.BigNumber.from('3600'), - // }, - // espressoTEEVerifier: espressoTEEVerifierProxy.address, - // } - // const deployParams = { - // config, - // batchPosters, - // batchPosterManager, - // validators, - // maxDataSize, - // nativeToken: nativeTokenAddress, - // deployFactoriesToL2, - // maxFeePerGasForRetryables, - // } - - // /// deploy it - // const receipt = await ( - // await rollupCreator.connect(userL1Wallet).createRollup(deployParams, { - // value: nativeToken ? BigNumber.from(0) : fee, - // }) - // ).wait() - // const l1TxReceipt = new L1TransactionReceipt(receipt) - - // // 1 init message + 8 msgs for deploying factories - // const events = l1TxReceipt.getMessageEvents() - // expect(events.length).to.be.eq(9) - - // // 1st retryable - // expect(events[1].inboxMessageEvent.messageNum.toString()).to.be.eq('1') - // await _verifyInboxMsg( - // events[1].inboxMessageEvent.data, - // await deployHelper.NICK_CREATE2_DEPLOYER(), - // await deployHelper.NICK_CREATE2_VALUE(), - // receipt.effectiveGasPrice, - // rollupCreator.address - // ) - // expect(events[2].inboxMessageEvent.messageNum.toString()).to.be.eq('2') - // expect(events[2].inboxMessageEvent.data).to.be.eq( - // await deployHelper.NICK_CREATE2_PAYLOAD() - // ) - - // // 2nd retryable - // expect(events[3].inboxMessageEvent.messageNum.toString()).to.be.eq('3') - // await _verifyInboxMsg( - // events[3].inboxMessageEvent.data, - // await deployHelper.ERC2470_DEPLOYER(), - // await deployHelper.ERC2470_VALUE(), - // receipt.effectiveGasPrice, - // rollupCreator.address - // ) - // expect(events[4].inboxMessageEvent.messageNum.toString()).to.be.eq('4') - // expect(events[4].inboxMessageEvent.data).to.be.eq( - // await deployHelper.ERC2470_PAYLOAD() - // ) - - // // 3rd retryable - // expect(events[5].inboxMessageEvent.messageNum.toString()).to.be.eq('5') - // await _verifyInboxMsg( - // events[5].inboxMessageEvent.data, - // await deployHelper.ZOLTU_CREATE2_DEPLOYER(), - // await deployHelper.ZOLTU_VALUE(), - // receipt.effectiveGasPrice, - // rollupCreator.address - // ) - // expect(events[6].inboxMessageEvent.messageNum.toString()).to.be.eq('6') - // expect(events[6].inboxMessageEvent.data).to.be.eq( - // await deployHelper.ZOLTU_CREATE2_PAYLOAD() - // ) - - // // 4th retryable - // expect(events[7].inboxMessageEvent.messageNum.toString()).to.be.eq('7') - // await _verifyInboxMsg( - // events[7].inboxMessageEvent.data, - // await deployHelper.ERC1820_DEPLOYER(), - // await deployHelper.ERC1820_VALUE(), - // receipt.effectiveGasPrice, - // rollupCreator.address - // ) - // expect(events[8].inboxMessageEvent.messageNum.toString()).to.be.eq('8') - // expect(events[8].inboxMessageEvent.data).to.be.eq( - // await deployHelper.ERC1820_PAYLOAD() - // ) - - // // check total amount to be minted is correct - // const { amountToBeMintedOnChildChain: amount1 } = await _decodeInboxMessage( - // events[1].inboxMessageEvent.data - // ) - // const { amountToBeMintedOnChildChain: amount2 } = await _decodeInboxMessage( - // events[3].inboxMessageEvent.data - // ) - // const { amountToBeMintedOnChildChain: amount3 } = await _decodeInboxMessage( - // events[5].inboxMessageEvent.data - // ) - // const { amountToBeMintedOnChildChain: amount4 } = await _decodeInboxMessage( - // events[7].inboxMessageEvent.data - // ) - // const amountToBeMinted = amount1.add(amount2).add(amount3).add(amount4) - // let expectedAmountToBeMinted = amountToBeMinted - // if (nativeToken && (await nativeToken.decimals()) < 18) { - // // sum up every retryable cost separately due to rounding effect possibly applied to each one - // const gasCost = maxFeePerGas.mul(BigNumber.from(21000)) - // expectedAmountToBeMinted = BigNumber.from(0) - // expectedAmountToBeMinted = expectedAmountToBeMinted.add( - // await _scaleFrom18ToNative( - // (await deployHelper.NICK_CREATE2_VALUE()).add(gasCost) - // ) - // ) - // expectedAmountToBeMinted = expectedAmountToBeMinted.add( - // await _scaleFrom18ToNative( - // (await deployHelper.ERC2470_VALUE()).add(gasCost) - // ) - // ) - // expectedAmountToBeMinted = expectedAmountToBeMinted.add( - // await _scaleFrom18ToNative( - // (await deployHelper.ZOLTU_VALUE()).add(gasCost) - // ) - // ) - // expectedAmountToBeMinted = expectedAmountToBeMinted.add( - // await _scaleFrom18ToNative( - // (await deployHelper.ERC1820_VALUE()).add(gasCost) - // ) - // ) - // expectedAmountToBeMinted = await _scaleFromNativeTo18( - // expectedAmountToBeMinted - // ) - // } - - // expect(amountToBeMinted).to.be.eq(expectedAmountToBeMinted) - - // // check amount locked (taken from deployer) matches total amount to be minted - // let amountTransferedFromDeployer - // if (nativeToken) { - // const transferLogs = receipt.logs.filter(log => - // log.topics.includes(nativeToken!.interface.getEventTopic('Transfer')) - // ) - // const decodedEvents = transferLogs.map( - // log => nativeToken!.interface.parseLog(log).args - // ) - // const transferedFromDeployer = decodedEvents.filter( - // log => log.from === userL1Wallet.address - // ) - // expect(transferedFromDeployer.length).to.be.eq(1) - // amountTransferedFromDeployer = transferedFromDeployer[0].value - // expect(await _scaleFromNativeTo18(amountTransferedFromDeployer)).to.be.eq( - // amountToBeMinted - // ) - // } else { - // amountTransferedFromDeployer = userL1NativeAssetBalance.sub( - // await l1Provider.getBalance(userL1Wallet.address) - // ) - // expect(amountTransferedFromDeployer).to.be.gte(amountToBeMinted) - // } - - // // check balances after retryable is processed - // let userL1NativeAssetBalanceAfter, bridgeBalanceAfter: BigNumber - // const rollupCreatedEvent = receipt.logs.filter(log => - // log.topics.includes( - // rollupCreator.interface.getEventTopic('RollupCreated') - // ) - // )[0] - // const decodedRollupCreatedEvent = - // rollupCreator.interface.parseLog(rollupCreatedEvent) - // const bridge = decodedRollupCreatedEvent.args.bridge - // if (nativeToken) { - // userL1NativeAssetBalanceAfter = await nativeToken.balanceOf( - // userL1Wallet.address - // ) - // expect( - // userL1NativeAssetBalance.sub(userL1NativeAssetBalanceAfter) - // ).to.be.eq(amountTransferedFromDeployer) - // bridgeBalanceAfter = await nativeToken.balanceOf(bridge) - // expect(bridgeBalanceAfter).to.be.eq(amountTransferedFromDeployer) - // } else { - // userL1NativeAssetBalanceAfter = await l1Provider.getBalance( - // userL1Wallet.address - // ) - // bridgeBalanceAfter = await l1Provider.getBalance(bridge) - // expect( - // userL1NativeAssetBalance.sub(userL1NativeAssetBalanceAfter) - // ).to.be.eq(amountTransferedFromDeployer) - // expect(bridgeBalanceAfter).to.be.eq(amountToBeMinted) - // } - // }) + it('can deploy deterministic factories to L2', async function () { + const rollupCreator = RollupCreator__factory.connect( + await _getRollupCreatorFromLogs(l1Provider), + l1Provider + ) + + const deployHelper = DeployHelper__factory.connect( + await rollupCreator.l2FactoriesDeployer(), + l1Provider + ) + + const inbox = l2Network.ethBridge.inbox + const maxFeePerGas = BigNumber.from('100000000') // 0.1 gwei + let fee = await deployHelper.getDeploymentTotalCost(inbox, maxFeePerGas) + + if (nativeToken) { + const decimals = await nativeToken.decimals() + if (decimals < 18) { + // if token has less than 18 decimals we need to sum fee costs per each retryable, + // as there could be rounding effect for each one of them + fee = BigNumber.from(0) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.NICK_CREATE2_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.ERC2470_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.ZOLTU_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.ERC1820_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + } else { + fee = await _scaleFrom18ToNative(fee) + } + + await ( + await nativeToken.connect(userL1Wallet).transfer(inbox, fee) + ).wait() + } + + // deploy factories + const receipt = await ( + await deployHelper + .connect(userL1Wallet) + .perform( + inbox, + nativeToken ? nativeToken.address : ethers.constants.AddressZero, + maxFeePerGas, + { value: nativeToken ? BigNumber.from(0) : fee } + ) + ).wait() + + const l1TxReceipt = new L1TransactionReceipt(receipt) + const messages = await l1TxReceipt.getL1ToL2Messages(l2Provider) + const messageResults = await Promise.all( + messages.map(message => message.waitForStatus()) + ) + + expect(messageResults[0].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) + expect(messageResults[1].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) + expect(messageResults[2].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) + expect(messageResults[3].status).to.be.eq(L1ToL2MessageStatus.REDEEMED) + + const deployedFactories = [ + '0x4e59b44847b379578588920ca78fbf26c0b4956c', + '0xce0042B868300000d44A59004Da54A005ffdcf9f', + '0x7A0D94F55792C434d74a40883C6ed8545E406D12', + '0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24', + ] + deployedFactories.forEach(async factory => { + expect((await l2Provider.getCode(factory)).length).to.be.gt( + EMPTY_CODE_LENGTH + ) + }) + }) + + it('can deploy deterministic factories to L2 through RollupCreator', async function () { + const rollupCreator = RollupCreator__factory.connect( + await _getRollupCreatorFromLogs(l1Provider), + l1Provider + ) + + const deployHelper = DeployHelper__factory.connect( + await rollupCreator.l2FactoriesDeployer(), + l1Provider + ) + + const inbox = l2Network.ethBridge.inbox + const maxFeePerGas = BigNumber.from('100000000') // 0.1 gwei + let fee = await deployHelper.getDeploymentTotalCost(inbox, maxFeePerGas) + if (nativeToken) { + const decimals = await nativeToken.decimals() + if (decimals < 18) { + // if token has less than 18 decimals we need to sum fee costs per each retryable, + // as there could be rounding effect for each one of them + fee = BigNumber.from(0) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.NICK_CREATE2_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.ERC2470_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.ZOLTU_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + fee = fee.add( + await _scaleFrom18ToNative( + ( + await deployHelper.ERC1820_VALUE() + ).add(maxFeePerGas.mul(BigNumber.from(21000))) + ) + ) + } else { + fee = await _scaleFrom18ToNative(fee) + } + + await ( + await nativeToken + .connect(userL1Wallet) + .approve(rollupCreator.address, fee) + ).wait() + } + + let userL1NativeAssetBalance: BigNumber + if (nativeToken) { + userL1NativeAssetBalance = await nativeToken.balanceOf( + userL1Wallet.address + ) + } else { + userL1NativeAssetBalance = await l1Provider.getBalance( + userL1Wallet.address + ) + } + + const batchPosters = [ethers.Wallet.createRandom().address] + const batchPosterManager = ethers.Wallet.createRandom().address + const validators = [ethers.Wallet.createRandom().address] + const maxDataSize = 104857 + const nativeTokenAddress = nativeToken + ? nativeToken.address + : ethers.constants.AddressZero + const deployFactoriesToL2 = true + const maxFeePerGasForRetryables = BigNumber.from('100000000') // 0.1 gwei + const espressoTEEVerifierFac = (await hardhatEthers.getContractFactory( + 'EspressoTEEVerifierMoc' + )) as EspressoTEEVerifierMock__factory + const espressoTEEVerifier = await espressoTEEVerifierFac.deploy() + + await espressoTEEVerifier.deployed() + + /// deploy params + const config = { + confirmPeriodBlocks: ethers.BigNumber.from('150'), + extraChallengeTimeBlocks: ethers.BigNumber.from('200'), + stakeToken: ethers.constants.AddressZero, + baseStake: ethers.utils.parseEther('1'), + wasmModuleRoot: + '0xda4e3ad5e7feacb817c21c8d0220da7650fe9051ece68a3f0b1c5d38bbb27b21', + owner: '0x72f7EEedF02C522242a4D3Bdc8aE6A8583aD7c5e', + loserStakeEscrow: ethers.constants.AddressZero, + chainId: ethers.BigNumber.from('433333'), + chainConfig: + '{"chainId":433333,"homesteadBlock":0,"daoForkBlock":null,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":0,"berlinBlock":0,"londonBlock":0,"clique":{"period":0,"epoch":0},"arbitrum":{"EnableArbOS":true,"AllowDebugPrecompiles":false,"DataAvailabilityCommittee":false,"InitialArbOSVersion":10,"InitialChainOwner":"0x72f7EEedF02C522242a4D3Bdc8aE6A8583aD7c5e","GenesisBlockNum":0}}', + genesisBlockNum: ethers.BigNumber.from('0'), + sequencerInboxMaxTimeVariation: { + delayBlocks: ethers.BigNumber.from('5760'), + futureBlocks: ethers.BigNumber.from('12'), + delaySeconds: ethers.BigNumber.from('86400'), + futureSeconds: ethers.BigNumber.from('3600'), + }, + espressoTEEVerifier: espressoTEEVerifier.address, + } + const deployParams = { + config, + batchPosters, + batchPosterManager, + validators, + maxDataSize, + nativeToken: nativeTokenAddress, + deployFactoriesToL2, + maxFeePerGasForRetryables, + } + + /// deploy it + const receipt = await ( + await rollupCreator.connect(userL1Wallet).createRollup(deployParams, { + value: nativeToken ? BigNumber.from(0) : fee, + }) + ).wait() + const l1TxReceipt = new L1TransactionReceipt(receipt) + + // 1 init message + 8 msgs for deploying factories + const events = l1TxReceipt.getMessageEvents() + expect(events.length).to.be.eq(9) + + // 1st retryable + expect(events[1].inboxMessageEvent.messageNum.toString()).to.be.eq('1') + await _verifyInboxMsg( + events[1].inboxMessageEvent.data, + await deployHelper.NICK_CREATE2_DEPLOYER(), + await deployHelper.NICK_CREATE2_VALUE(), + receipt.effectiveGasPrice, + rollupCreator.address + ) + expect(events[2].inboxMessageEvent.messageNum.toString()).to.be.eq('2') + expect(events[2].inboxMessageEvent.data).to.be.eq( + await deployHelper.NICK_CREATE2_PAYLOAD() + ) + + // 2nd retryable + expect(events[3].inboxMessageEvent.messageNum.toString()).to.be.eq('3') + await _verifyInboxMsg( + events[3].inboxMessageEvent.data, + await deployHelper.ERC2470_DEPLOYER(), + await deployHelper.ERC2470_VALUE(), + receipt.effectiveGasPrice, + rollupCreator.address + ) + expect(events[4].inboxMessageEvent.messageNum.toString()).to.be.eq('4') + expect(events[4].inboxMessageEvent.data).to.be.eq( + await deployHelper.ERC2470_PAYLOAD() + ) + + // 3rd retryable + expect(events[5].inboxMessageEvent.messageNum.toString()).to.be.eq('5') + await _verifyInboxMsg( + events[5].inboxMessageEvent.data, + await deployHelper.ZOLTU_CREATE2_DEPLOYER(), + await deployHelper.ZOLTU_VALUE(), + receipt.effectiveGasPrice, + rollupCreator.address + ) + expect(events[6].inboxMessageEvent.messageNum.toString()).to.be.eq('6') + expect(events[6].inboxMessageEvent.data).to.be.eq( + await deployHelper.ZOLTU_CREATE2_PAYLOAD() + ) + + // 4th retryable + expect(events[7].inboxMessageEvent.messageNum.toString()).to.be.eq('7') + await _verifyInboxMsg( + events[7].inboxMessageEvent.data, + await deployHelper.ERC1820_DEPLOYER(), + await deployHelper.ERC1820_VALUE(), + receipt.effectiveGasPrice, + rollupCreator.address + ) + expect(events[8].inboxMessageEvent.messageNum.toString()).to.be.eq('8') + expect(events[8].inboxMessageEvent.data).to.be.eq( + await deployHelper.ERC1820_PAYLOAD() + ) + + // check total amount to be minted is correct + const { amountToBeMintedOnChildChain: amount1 } = await _decodeInboxMessage( + events[1].inboxMessageEvent.data + ) + const { amountToBeMintedOnChildChain: amount2 } = await _decodeInboxMessage( + events[3].inboxMessageEvent.data + ) + const { amountToBeMintedOnChildChain: amount3 } = await _decodeInboxMessage( + events[5].inboxMessageEvent.data + ) + const { amountToBeMintedOnChildChain: amount4 } = await _decodeInboxMessage( + events[7].inboxMessageEvent.data + ) + const amountToBeMinted = amount1.add(amount2).add(amount3).add(amount4) + let expectedAmountToBeMinted = amountToBeMinted + if (nativeToken && (await nativeToken.decimals()) < 18) { + // sum up every retryable cost separately due to rounding effect possibly applied to each one + const gasCost = maxFeePerGas.mul(BigNumber.from(21000)) + expectedAmountToBeMinted = BigNumber.from(0) + expectedAmountToBeMinted = expectedAmountToBeMinted.add( + await _scaleFrom18ToNative( + (await deployHelper.NICK_CREATE2_VALUE()).add(gasCost) + ) + ) + expectedAmountToBeMinted = expectedAmountToBeMinted.add( + await _scaleFrom18ToNative( + (await deployHelper.ERC2470_VALUE()).add(gasCost) + ) + ) + expectedAmountToBeMinted = expectedAmountToBeMinted.add( + await _scaleFrom18ToNative( + (await deployHelper.ZOLTU_VALUE()).add(gasCost) + ) + ) + expectedAmountToBeMinted = expectedAmountToBeMinted.add( + await _scaleFrom18ToNative( + (await deployHelper.ERC1820_VALUE()).add(gasCost) + ) + ) + expectedAmountToBeMinted = await _scaleFromNativeTo18( + expectedAmountToBeMinted + ) + } + + expect(amountToBeMinted).to.be.eq(expectedAmountToBeMinted) + + // check amount locked (taken from deployer) matches total amount to be minted + let amountTransferedFromDeployer + if (nativeToken) { + const transferLogs = receipt.logs.filter(log => + log.topics.includes(nativeToken!.interface.getEventTopic('Transfer')) + ) + const decodedEvents = transferLogs.map( + log => nativeToken!.interface.parseLog(log).args + ) + const transferedFromDeployer = decodedEvents.filter( + log => log.from === userL1Wallet.address + ) + expect(transferedFromDeployer.length).to.be.eq(1) + amountTransferedFromDeployer = transferedFromDeployer[0].value + expect(await _scaleFromNativeTo18(amountTransferedFromDeployer)).to.be.eq( + amountToBeMinted + ) + } else { + amountTransferedFromDeployer = userL1NativeAssetBalance.sub( + await l1Provider.getBalance(userL1Wallet.address) + ) + expect(amountTransferedFromDeployer).to.be.gte(amountToBeMinted) + } + + // check balances after retryable is processed + let userL1NativeAssetBalanceAfter, bridgeBalanceAfter: BigNumber + const rollupCreatedEvent = receipt.logs.filter(log => + log.topics.includes( + rollupCreator.interface.getEventTopic('RollupCreated') + ) + )[0] + const decodedRollupCreatedEvent = + rollupCreator.interface.parseLog(rollupCreatedEvent) + const bridge = decodedRollupCreatedEvent.args.bridge + if (nativeToken) { + userL1NativeAssetBalanceAfter = await nativeToken.balanceOf( + userL1Wallet.address + ) + expect( + userL1NativeAssetBalance.sub(userL1NativeAssetBalanceAfter) + ).to.be.eq(amountTransferedFromDeployer) + bridgeBalanceAfter = await nativeToken.balanceOf(bridge) + expect(bridgeBalanceAfter).to.be.eq(amountTransferedFromDeployer) + } else { + userL1NativeAssetBalanceAfter = await l1Provider.getBalance( + userL1Wallet.address + ) + bridgeBalanceAfter = await l1Provider.getBalance(bridge) + expect( + userL1NativeAssetBalance.sub(userL1NativeAssetBalanceAfter) + ).to.be.eq(amountTransferedFromDeployer) + expect(bridgeBalanceAfter).to.be.eq(amountToBeMinted) + } + }) }) async function _verifyInboxMsg( diff --git a/test/foundry/EspressoTEEVerifier.t.sol b/test/foundry/EspressoTEEVerifier.t.sol index d614decc..feddc915 100644 --- a/test/foundry/EspressoTEEVerifier.t.sol +++ b/test/foundry/EspressoTEEVerifier.t.sol @@ -3,38 +3,29 @@ pragma solidity ^0.8.20; import "forge-std/Test.sol"; import {EspressoTEEVerifier} from "../../src/bridge/EspressoTEEVerifier.sol"; -import { - TransparentUpgradeableProxy -} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import { - AutomataDcapAttestation -} from "@automata-network/dcap-attestation/contracts/AutomataDcapAttestation.sol"; -import {PCCSRouter} from "@automata-network/dcap-attestation/contracts/PCCSRouter.sol"; - -import {PCCSSetupBase} from "@automata-network/dcap-attestation/test/utils/PCCSSetupBase.sol"; -import {RiscZeroSetup} from "@automata-network/dcap-attestation/test/utils/RiscZeroSetup.sol"; - -contract EspressoTEEVerifierTest is Test, PCCSSetupBase, RiscZeroSetup { + +contract EspressoTEEVerifierTest is Test { address proxyAdmin = address(140); address adminTEE = address(141); address fakeAddress = address(145); EspressoTEEVerifier espressoTEEVerifier; - PCCSRouter pccsRouter; - bytes32 imageId = vm.envBytes32("DCAP_IMAGE_ID"); - - function setUp() public override { - super.setUp(); + bytes32 reportDataHash = + bytes32(0x739f5f48d929cc121c080ec6527a22be3c69bad5c40606cd098a9fa7ed971f1b); + bytes32 mrEnclave = bytes32(0x51dfe95acffa8a4075b716257c836895af9202a5fd56c8c2208dacb79c659ff0); + bytes32 mrSigner = bytes32(0x0c8242bba090f54b10de0c2d1ca4b633b9c08b7178451c71d737c214b72fc836); - // PCCS Setup - pccsRouter = setupPccsRouter(); - pcsDaoUpserts(); - espressoTEEVerifier = new EspressoTEEVerifier(address(pccsRouter)); - - string memory tcbInfoPath = "/test/foundry/configs/tcbinfo.json"; - string memory qeIdPath = "/test/foundry/configs/tee_identity.json"; - qeIdDaoUpsert(3, qeIdPath); - fmspcTcbDaoUpsert(tcbInfoPath); + function setUp() public { + vm.createSelectFork("https://rpc.ankr.com/eth_sepolia"); + // Get the instance of the DCAP Attestation QuoteVerifier on the Arbitrum Sepolia Rollup + vm.startPrank(adminTEE); + espressoTEEVerifier = new EspressoTEEVerifier( + mrEnclave, + mrSigner, + // Address of the deployed V3Verifier contract + address(0x6E64769A13617f528a2135692484B681Ee1a7169) + ); + vm.stopPrank(); } /* @@ -43,10 +34,10 @@ contract EspressoTEEVerifierTest is Test, PCCSSetupBase, RiscZeroSetup { function testVerifyQuoteValid() public { vm.startPrank(adminTEE); - string memory quotePath = "/test/foundry/configs/attestation.bin"; + string memory quotePath = "/test/foundry/configs/valid_quote.bin"; string memory inputFile = string.concat(vm.projectRoot(), quotePath); bytes memory sampleQuote = vm.readFileBinary(inputFile); - bool success = espressoTEEVerifier.verify(sampleQuote); + bool success = espressoTEEVerifier.verify(sampleQuote, reportDataHash); assertEq(success, true); vm.stopPrank(); } @@ -58,7 +49,97 @@ contract EspressoTEEVerifierTest is Test, PCCSSetupBase, RiscZeroSetup { string memory quotePath = "/test/foundry/configs/incorrect_attestation_quote.bin"; string memory inputFile = string.concat(vm.projectRoot(), quotePath); bytes memory invalidQuote = vm.readFileBinary(inputFile); - bool success = espressoTEEVerifier.verify(invalidQuote); + bool success = espressoTEEVerifier.verify(invalidQuote, reportDataHash); + assertEq(success, false); + } + + /** + Test incorrect report data hash + */ + + function testIncorrectReportDataHash() public { + vm.startPrank(adminTEE); + + string memory quotePath = "/test/foundry/configs/attestation.bin"; + string memory inputFile = string.concat(vm.projectRoot(), quotePath); + bytes memory sampleQuote = vm.readFileBinary(inputFile); + bool success = espressoTEEVerifier.verify(sampleQuote, bytes32(0)); + assertEq(success, false); + } + + /** + Test incorrect mrEnclave + */ + function testIncorrectMrEnclave() public { + vm.startPrank(adminTEE); + + string memory quotePath = "/test/foundry/configs/attestation.bin"; + string memory inputFile = string.concat(vm.projectRoot(), quotePath); + bytes memory sampleQuote = vm.readFileBinary(inputFile); + espressoTEEVerifier = new EspressoTEEVerifier( + bytes32(0x51dfe95acffa8a4075b716257c836895af9202a5fd56c8c2208dacb79c659ff1), + mrSigner, + address(0x6E64769A13617f528a2135692484B681Ee1a7169) + ); + bool success = espressoTEEVerifier.verify(sampleQuote, reportDataHash); + assertEq(success, false); + } + + /** + Test incorrect mrSigner + */ + function testIncorrectMrSigner() public { + vm.startPrank(adminTEE); + + string memory quotePath = "/test/foundry/configs/attestation.bin"; + string memory inputFile = string.concat(vm.projectRoot(), quotePath); + bytes memory sampleQuote = vm.readFileBinary(inputFile); + espressoTEEVerifier = new EspressoTEEVerifier( + mrEnclave, + bytes32(0x51dfe95acffa8a4075b716257c836895af9202a5fd56c8c2208dacb79c659ff5), + address(0x6E64769A13617f528a2135692484B681Ee1a7169) + ); + bool success = espressoTEEVerifier.verify(sampleQuote, reportDataHash); assertEq(success, false); } + + /** + Test set owner + */ + function testSetOwner() public { + vm.startPrank(adminTEE); + + address newOwner = address(142); + espressoTEEVerifier.setOwner(newOwner); + assertEq(espressoTEEVerifier.owner(), newOwner); + vm.stopPrank(); + } + + /** + Test set mrEnclave + */ + function testSetMrEnclave() public { + vm.startPrank(adminTEE); + + bytes32 newMrEnclave = bytes32( + 0x1234567890123456789012345678901234567890123456789012345678901234 + ); + espressoTEEVerifier.setMrEnclave(newMrEnclave); + assertEq(espressoTEEVerifier.mrEnclave(), newMrEnclave); + vm.stopPrank(); + } + + /** + Test set mrSigner + */ + function testSetMrSigner() public { + vm.startPrank(adminTEE); + + bytes32 newMrSigner = bytes32( + 0x1234567890123456789012345678901234567890123456789012345678901234 + ); + espressoTEEVerifier.setMrSigner(newMrSigner); + assertEq(espressoTEEVerifier.mrSigner(), newMrSigner); + vm.stopPrank(); + } } diff --git a/test/foundry/SequencerInbox.t.sol b/test/foundry/SequencerInbox.t.sol index 84301e87..6abacb47 100644 --- a/test/foundry/SequencerInbox.t.sol +++ b/test/foundry/SequencerInbox.t.sol @@ -11,16 +11,9 @@ import {EspressoTEEVerifier} from "../../src/bridge/EspressoTEEVerifier.sol"; import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import { - AutomataDcapAttestation -} from "@automata-network/dcap-attestation/contracts/AutomataDcapAttestation.sol"; import { V3QuoteVerifier } from "@automata-network/dcap-attestation/contracts/verifiers/V3QuoteVerifier.sol"; -import {PCCSRouter} from "@automata-network/dcap-attestation/contracts/PCCSRouter.sol"; - -import {PCCSSetupBase} from "@automata-network/dcap-attestation/test/utils/PCCSSetupBase.sol"; -import {RiscZeroSetup} from "@automata-network/dcap-attestation/test/utils/RiscZeroSetup.sol"; contract RollupMock { address public immutable owner; @@ -30,7 +23,7 @@ contract RollupMock { } } -contract SequencerInboxTest is Test, PCCSSetupBase, RiscZeroSetup { +contract SequencerInboxTest is Test { // cannot reference events outside of the original contract until 0.8.21 // we currently use 0.8.9 event MessageDelivered( @@ -66,6 +59,8 @@ contract SequencerInboxTest is Test, PCCSSetupBase, RiscZeroSetup { }); address dummyInbox = address(139); address proxyAdmin = address(140); + bytes32 mrEnclave = bytes32(0x51dfe95acffa8a4075b716257c836895af9202a5fd56c8c2208dacb79c659ff0); + bytes32 mrSigner = bytes32(0x0c8242bba090f54b10de0c2d1ca4b633b9c08b7178451c71d737c214b72fc836); IReader4844 dummyReader4844 = IReader4844(address(137)); uint256 public constant MAX_DATA_SIZE = 117964; @@ -74,25 +69,19 @@ contract SequencerInboxTest is Test, PCCSSetupBase, RiscZeroSetup { EspressoTEEVerifier espressoTEEVerifier; V3QuoteVerifier quoteVerifier; - PCCSRouter pccsRouter; bytes sampleQuote; bytes invalidQuote; - function setUp() public override { - super.setUp(); + function setUp() public { vm.startPrank(adminTEE); + vm.createSelectFork("https://rpc.ankr.com/eth_sepolia"); - // PCCS Setup - pccsRouter = setupPccsRouter(); - pcsDaoUpserts(); - - string memory tcbInfoPath = "/test/foundry/configs/tcbinfo.json"; - string memory qeIdPath = "/test/foundry/configs/tee_identity.json"; - qeIdDaoUpsert(3, qeIdPath); - fmspcTcbDaoUpsert(tcbInfoPath); - - // PCCS Setup - espressoTEEVerifier = new EspressoTEEVerifier(address(pccsRouter)); + espressoTEEVerifier = new EspressoTEEVerifier( + mrEnclave, + mrSigner, + // Address of the deployed V3Verifier contract + address(0x6E64769A13617f528a2135692484B681Ee1a7169) + ); string memory quotePath = "/test/foundry/configs/attestation.bin"; string memory inputFile = string.concat(vm.projectRoot(), quotePath); @@ -287,7 +276,7 @@ contract SequencerInboxTest is Test, PCCSSetupBase, RiscZeroSetup { vm.prank(tx.origin); string memory quotePath = "/test/foundry/configs/attestation.bin"; string memory inputFile = string.concat(vm.projectRoot(), quotePath); - bytes memory sampleQuote = vm.readFileBinary(inputFile); + sampleQuote = vm.readFileBinary(inputFile); seqInbox.addSequencerL2BatchFromOrigin( sequenceNumber,