@arbitrum/nitro-contracts 1.0.0-beta.5 → 1.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -2
- package/src/bridge/Bridge.sol +138 -32
- package/src/bridge/IBridge.sol +34 -14
- package/src/bridge/IDelayedMessageProvider.sol +15 -0
- package/src/bridge/IInbox.sol +8 -19
- package/src/bridge/IOutbox.sol +43 -23
- package/src/bridge/IOwnable.sol +10 -0
- package/src/bridge/ISequencerInbox.sol +30 -32
- package/src/bridge/Inbox.sol +133 -35
- package/src/bridge/Outbox.sol +145 -33
- package/src/bridge/SequencerInbox.sol +179 -60
- package/src/challenge/ChallengeLib.sol +0 -2
- package/src/challenge/ChallengeManager.sol +4 -8
- package/src/challenge/IChallengeManager.sol +1 -1
- package/src/libraries/Error.sol +113 -0
- package/src/libraries/IGasRefunder.sol +15 -14
- package/src/libraries/MerkleLib.sol +11 -2
- package/src/libraries/MessageTypes.sol +1 -0
- package/src/mocks/BridgeStub.sol +69 -21
- package/src/mocks/InboxStub.sol +2 -0
- package/src/mocks/SequencerInboxStub.sol +10 -8
- package/src/mocks/Simple.sol +8 -0
- package/src/node-interface/NodeInterface.sol +62 -4
- package/src/osp/IOneStepProver.sol +1 -2
- package/src/osp/OneStepProver0.sol +1 -87
- package/src/osp/OneStepProverHostIo.sol +5 -6
- package/src/osp/OneStepProverMath.sol +37 -27
- package/src/osp/OneStepProverMemory.sol +3 -4
- package/src/precompiles/ArbAggregator.sol +23 -33
- package/src/precompiles/ArbBLS.sol +1 -43
- package/src/precompiles/ArbGasInfo.sol +10 -19
- package/src/precompiles/ArbOwner.sol +21 -15
- package/src/precompiles/ArbRetryableTx.sol +10 -1
- package/src/precompiles/ArbSys.sol +4 -4
- package/src/precompiles/ArbosActs.sol +9 -2
- package/src/rollup/BridgeCreator.sol +23 -28
- package/src/rollup/IRollupCore.sol +3 -3
- package/src/rollup/{IRollupEventBridge.sol → IRollupEventInbox.sol} +2 -2
- package/src/rollup/IRollupLogic.sol +21 -18
- package/src/rollup/RollupAdminLogic.sol +72 -34
- package/src/rollup/RollupCore.sol +20 -9
- package/src/rollup/RollupCreator.sol +21 -11
- package/src/rollup/{RollupEventBridge.sol → RollupEventInbox.sol} +10 -10
- package/src/rollup/RollupLib.sol +21 -5
- package/src/rollup/RollupUserLogic.sol +10 -18
- package/src/rollup/ValidatorWallet.sol +125 -8
- package/src/rollup/ValidatorWalletCreator.sol +11 -6
- package/src/state/Deserialize.sol +3 -22
- package/src/state/GlobalState.sol +7 -0
- package/src/state/Instructions.sol +2 -10
- package/src/state/Machine.sol +0 -4
- package/src/state/ModuleMemory.sol +2 -1
- package/src/state/Value.sol +2 -3
- package/src/test-helpers/BridgeTester.sol +233 -0
- package/src/test-helpers/InterfaceCompatibilityTester.sol +11 -0
- package/src/test-helpers/OutboxWithoutOptTester.sol +214 -0
- package/src/test-helpers/RollupMock.sol +21 -0
- package/src/bridge/IMessageProvider.sol +0 -11
- package/src/state/PcStack.sol +0 -32
| @@ -4,10 +4,30 @@ | |
| 4 4 |  | 
| 5 5 | 
             
            pragma solidity ^0.8.0;
         | 
| 6 6 |  | 
| 7 | 
            +
            import {
         | 
| 8 | 
            +
                AlreadyInit,
         | 
| 9 | 
            +
                HadZeroInit,
         | 
| 10 | 
            +
                NotOrigin,
         | 
| 11 | 
            +
                DataTooLarge,
         | 
| 12 | 
            +
                NotRollup,
         | 
| 13 | 
            +
                DelayedBackwards,
         | 
| 14 | 
            +
                DelayedTooFar,
         | 
| 15 | 
            +
                ForceIncludeBlockTooSoon,
         | 
| 16 | 
            +
                ForceIncludeTimeTooSoon,
         | 
| 17 | 
            +
                IncorrectMessagePreimage,
         | 
| 18 | 
            +
                NotBatchPoster,
         | 
| 19 | 
            +
                BadSequencerNumber,
         | 
| 20 | 
            +
                DataNotAuthenticated,
         | 
| 21 | 
            +
                AlreadyValidDASKeyset,
         | 
| 22 | 
            +
                NoSuchKeyset
         | 
| 23 | 
            +
            } from "../libraries/Error.sol";
         | 
| 7 24 | 
             
            import "./IBridge.sol";
         | 
| 25 | 
            +
            import "./IInbox.sol";
         | 
| 8 26 | 
             
            import "./ISequencerInbox.sol";
         | 
| 27 | 
            +
            import "../rollup/IRollupLogic.sol";
         | 
| 9 28 | 
             
            import "./Messages.sol";
         | 
| 10 29 |  | 
| 30 | 
            +
            import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol";
         | 
| 11 31 | 
             
            import {GasRefundEnabled, IGasRefunder} from "../libraries/IGasRefunder.sol";
         | 
| 12 32 | 
             
            import "../libraries/DelegateCallAware.sol";
         | 
| 13 33 | 
             
            import {MAX_DATA_SIZE} from "../libraries/Constants.sol";
         | 
| @@ -20,10 +40,9 @@ import {MAX_DATA_SIZE} from "../libraries/Constants.sol"; | |
| 20 40 | 
             
             * sequencer within a time limit they can be force included into the rollup inbox by anyone.
         | 
| 21 41 | 
             
             */
         | 
| 22 42 | 
             
            contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox {
         | 
| 23 | 
            -
                bytes32[] public override inboxAccs;
         | 
| 24 43 | 
             
                uint256 public totalDelayedMessagesRead;
         | 
| 25 44 |  | 
| 26 | 
            -
                IBridge public  | 
| 45 | 
            +
                IBridge public bridge;
         | 
| 27 46 |  | 
| 28 47 | 
             
                /// @dev The size of the batch header
         | 
| 29 48 | 
             
                uint256 public constant HEADER_LENGTH = 40;
         | 
| @@ -31,19 +50,29 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox | |
| 31 50 | 
             
                /// the sequencer inbox has authenticated the data. Currently not used.
         | 
| 32 51 | 
             
                bytes1 public constant DATA_AUTHENTICATED_FLAG = 0x40;
         | 
| 33 52 |  | 
| 34 | 
            -
                 | 
| 53 | 
            +
                IOwnable public rollup;
         | 
| 35 54 | 
             
                mapping(address => bool) public isBatchPoster;
         | 
| 36 55 | 
             
                ISequencerInbox.MaxTimeVariation public maxTimeVariation;
         | 
| 37 56 |  | 
| 57 | 
            +
                struct DasKeySetInfo {
         | 
| 58 | 
            +
                    bool isValidKeyset;
         | 
| 59 | 
            +
                    uint64 creationBlock;
         | 
| 60 | 
            +
                }
         | 
| 61 | 
            +
                mapping(bytes32 => DasKeySetInfo) public dasKeySetInfo;
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                modifier onlyRollupOwner() {
         | 
| 64 | 
            +
                    if (msg.sender != rollup.owner()) revert NotOwner(msg.sender, address(rollup));
         | 
| 65 | 
            +
                    _;
         | 
| 66 | 
            +
                }
         | 
| 67 | 
            +
             | 
| 38 68 | 
             
                function initialize(
         | 
| 39 | 
            -
                    IBridge  | 
| 40 | 
            -
                    address rollup_,
         | 
| 69 | 
            +
                    IBridge bridge_,
         | 
| 41 70 | 
             
                    ISequencerInbox.MaxTimeVariation calldata maxTimeVariation_
         | 
| 42 71 | 
             
                ) external onlyDelegated {
         | 
| 43 | 
            -
                    if ( | 
| 44 | 
            -
                    if ( | 
| 45 | 
            -
                     | 
| 46 | 
            -
                    rollup =  | 
| 72 | 
            +
                    if (bridge != IBridge(address(0))) revert AlreadyInit();
         | 
| 73 | 
            +
                    if (bridge_ == IBridge(address(0))) revert HadZeroInit();
         | 
| 74 | 
            +
                    bridge = bridge_;
         | 
| 75 | 
            +
                    rollup = bridge_.rollup();
         | 
| 47 76 | 
             
                    maxTimeVariation = maxTimeVariation_;
         | 
| 48 77 | 
             
                }
         | 
| 49 78 |  | 
| @@ -98,22 +127,24 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox | |
| 98 127 | 
             
                    // Verify that message hash represents the last message sequence of delayed message to be included
         | 
| 99 128 | 
             
                    bytes32 prevDelayedAcc = 0;
         | 
| 100 129 | 
             
                    if (_totalDelayedMessagesRead > 1) {
         | 
| 101 | 
            -
                        prevDelayedAcc =  | 
| 130 | 
            +
                        prevDelayedAcc = bridge.delayedInboxAccs(_totalDelayedMessagesRead - 2);
         | 
| 102 131 | 
             
                    }
         | 
| 103 132 | 
             
                    if (
         | 
| 104 | 
            -
                         | 
| 133 | 
            +
                        bridge.delayedInboxAccs(_totalDelayedMessagesRead - 1) !=
         | 
| 105 134 | 
             
                        Messages.accumulateInboxMessage(prevDelayedAcc, messageHash)
         | 
| 106 135 | 
             
                    ) revert IncorrectMessagePreimage();
         | 
| 107 136 |  | 
| 108 137 | 
             
                    (bytes32 dataHash, TimeBounds memory timeBounds) = formEmptyDataHash(
         | 
| 109 138 | 
             
                        _totalDelayedMessagesRead
         | 
| 110 139 | 
             
                    );
         | 
| 111 | 
            -
                    ( | 
| 112 | 
            -
                         | 
| 113 | 
            -
                         | 
| 114 | 
            -
             | 
| 140 | 
            +
                    (
         | 
| 141 | 
            +
                        uint256 seqMessageIndex,
         | 
| 142 | 
            +
                        bytes32 beforeAcc,
         | 
| 143 | 
            +
                        bytes32 delayedAcc,
         | 
| 144 | 
            +
                        bytes32 afterAcc
         | 
| 145 | 
            +
                    ) = addSequencerL2BatchImpl(dataHash, _totalDelayedMessagesRead, 0);
         | 
| 115 146 | 
             
                    emit SequencerBatchDelivered(
         | 
| 116 | 
            -
                         | 
| 147 | 
            +
                        seqMessageIndex,
         | 
| 117 148 | 
             
                        beforeAcc,
         | 
| 118 149 | 
             
                        afterAcc,
         | 
| 119 150 | 
             
                        delayedAcc,
         | 
| @@ -128,21 +159,24 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox | |
| 128 159 | 
             
                    bytes calldata data,
         | 
| 129 160 | 
             
                    uint256 afterDelayedMessagesRead,
         | 
| 130 161 | 
             
                    IGasRefunder gasRefunder
         | 
| 131 | 
            -
                ) external  | 
| 162 | 
            +
                ) external refundsGas(gasRefunder) {
         | 
| 132 163 | 
             
                    // solhint-disable-next-line avoid-tx-origin
         | 
| 133 164 | 
             
                    if (msg.sender != tx.origin) revert NotOrigin();
         | 
| 134 165 | 
             
                    if (!isBatchPoster[msg.sender]) revert NotBatchPoster();
         | 
| 135 | 
            -
                    if (inboxAccs.length != sequenceNumber) revert BadSequencerNumber();
         | 
| 136 166 | 
             
                    (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash(
         | 
| 137 167 | 
             
                        data,
         | 
| 138 168 | 
             
                        afterDelayedMessagesRead
         | 
| 139 169 | 
             
                    );
         | 
| 140 | 
            -
                    ( | 
| 141 | 
            -
                         | 
| 142 | 
            -
                         | 
| 143 | 
            -
             | 
| 170 | 
            +
                    (
         | 
| 171 | 
            +
                        uint256 seqMessageIndex,
         | 
| 172 | 
            +
                        bytes32 beforeAcc,
         | 
| 173 | 
            +
                        bytes32 delayedAcc,
         | 
| 174 | 
            +
                        bytes32 afterAcc
         | 
| 175 | 
            +
                    ) = addSequencerL2BatchImpl(dataHash, afterDelayedMessagesRead, data.length);
         | 
| 176 | 
            +
                    if (seqMessageIndex != sequenceNumber)
         | 
| 177 | 
            +
                        revert BadSequencerNumber(seqMessageIndex, sequenceNumber);
         | 
| 144 178 | 
             
                    emit SequencerBatchDelivered(
         | 
| 145 | 
            -
                         | 
| 179 | 
            +
                        sequenceNumber,
         | 
| 146 180 | 
             
                        beforeAcc,
         | 
| 147 181 | 
             
                        afterAcc,
         | 
| 148 182 | 
             
                        delayedAcc,
         | 
| @@ -157,18 +191,23 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox | |
| 157 191 | 
             
                    bytes calldata data,
         | 
| 158 192 | 
             
                    uint256 afterDelayedMessagesRead,
         | 
| 159 193 | 
             
                    IGasRefunder gasRefunder
         | 
| 160 | 
            -
                ) external override  | 
| 161 | 
            -
                    if (!isBatchPoster[msg.sender] && msg.sender != rollup) revert NotBatchPoster();
         | 
| 162 | 
            -
                    if (inboxAccs.length != sequenceNumber) revert BadSequencerNumber();
         | 
| 194 | 
            +
                ) external override refundsGas(gasRefunder) {
         | 
| 195 | 
            +
                    if (!isBatchPoster[msg.sender] && msg.sender != address(rollup)) revert NotBatchPoster();
         | 
| 163 196 |  | 
| 164 197 | 
             
                    (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash(
         | 
| 165 198 | 
             
                        data,
         | 
| 166 199 | 
             
                        afterDelayedMessagesRead
         | 
| 167 200 | 
             
                    );
         | 
| 168 | 
            -
                     | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 201 | 
            +
                    // we set the calldata length posted to 0 here since the caller isn't the origin
         | 
| 202 | 
            +
                    // of the tx, so they might have not paid tx input cost for the calldata
         | 
| 203 | 
            +
                    (
         | 
| 204 | 
            +
                        uint256 seqMessageIndex,
         | 
| 205 | 
            +
                        bytes32 beforeAcc,
         | 
| 206 | 
            +
                        bytes32 delayedAcc,
         | 
| 207 | 
            +
                        bytes32 afterAcc
         | 
| 208 | 
            +
                    ) = addSequencerL2BatchImpl(dataHash, afterDelayedMessagesRead, 0);
         | 
| 209 | 
            +
                    if (seqMessageIndex != sequenceNumber)
         | 
| 210 | 
            +
                        revert BadSequencerNumber(seqMessageIndex, sequenceNumber);
         | 
| 172 211 | 
             
                    emit SequencerBatchDelivered(
         | 
| 173 212 | 
             
                        sequenceNumber,
         | 
| 174 213 | 
             
                        beforeAcc,
         | 
| @@ -181,6 +220,22 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox | |
| 181 220 | 
             
                    emit SequencerBatchData(sequenceNumber, data);
         | 
| 182 221 | 
             
                }
         | 
| 183 222 |  | 
| 223 | 
            +
                modifier validateBatchData(bytes calldata data) {
         | 
| 224 | 
            +
                    uint256 fullDataLen = HEADER_LENGTH + data.length;
         | 
| 225 | 
            +
                    if (fullDataLen > MAX_DATA_SIZE) revert DataTooLarge(fullDataLen, MAX_DATA_SIZE);
         | 
| 226 | 
            +
                    if (data.length > 0 && (data[0] & DATA_AUTHENTICATED_FLAG) == DATA_AUTHENTICATED_FLAG) {
         | 
| 227 | 
            +
                        revert DataNotAuthenticated();
         | 
| 228 | 
            +
                    }
         | 
| 229 | 
            +
                    // the first byte is used to identify the type of batch data
         | 
| 230 | 
            +
                    // das batches expect to have the type byte set, followed by the keyset (so they should have at least 33 bytes)
         | 
| 231 | 
            +
                    if (data.length >= 33 && data[0] & 0x80 != 0) {
         | 
| 232 | 
            +
                        // we skip the first byte, then read the next 32 bytes for the keyset
         | 
| 233 | 
            +
                        bytes32 dasKeysetHash = bytes32(data[1:33]);
         | 
| 234 | 
            +
                        if (!dasKeySetInfo[dasKeysetHash].isValidKeyset) revert NoSuchKeyset(dasKeysetHash);
         | 
| 235 | 
            +
                    }
         | 
| 236 | 
            +
                    _;
         | 
| 237 | 
            +
                }
         | 
| 238 | 
            +
             | 
| 184 239 | 
             
                function packHeader(uint256 afterDelayedMessagesRead)
         | 
| 185 240 | 
             
                    internal
         | 
| 186 241 | 
             
                    view
         | 
| @@ -202,25 +257,12 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox | |
| 202 257 | 
             
                function formDataHash(bytes calldata data, uint256 afterDelayedMessagesRead)
         | 
| 203 258 | 
             
                    internal
         | 
| 204 259 | 
             
                    view
         | 
| 260 | 
            +
                    validateBatchData(data)
         | 
| 205 261 | 
             
                    returns (bytes32, TimeBounds memory)
         | 
| 206 262 | 
             
                {
         | 
| 207 | 
            -
                    uint256 fullDataLen = HEADER_LENGTH + data.length;
         | 
| 208 | 
            -
                    if (fullDataLen < HEADER_LENGTH) revert DataLengthOverflow();
         | 
| 209 | 
            -
                    if (fullDataLen > MAX_DATA_SIZE) revert DataTooLarge(fullDataLen, MAX_DATA_SIZE);
         | 
| 210 | 
            -
                    bytes memory fullData = new bytes(fullDataLen);
         | 
| 211 263 | 
             
                    (bytes memory header, TimeBounds memory timeBounds) = packHeader(afterDelayedMessagesRead);
         | 
| 212 | 
            -
             | 
| 213 | 
            -
                     | 
| 214 | 
            -
                        fullData[i] = header[i];
         | 
| 215 | 
            -
                    }
         | 
| 216 | 
            -
                    if (data.length > 0 && (data[0] & DATA_AUTHENTICATED_FLAG) == DATA_AUTHENTICATED_FLAG) {
         | 
| 217 | 
            -
                        revert DataNotAuthenticated();
         | 
| 218 | 
            -
                    }
         | 
| 219 | 
            -
                    // copy data into fullData at offset of HEADER_LENGTH (the extra 32 offset is because solidity puts the array len first)
         | 
| 220 | 
            -
                    assembly {
         | 
| 221 | 
            -
                        calldatacopy(add(fullData, add(HEADER_LENGTH, 32)), data.offset, data.length)
         | 
| 222 | 
            -
                    }
         | 
| 223 | 
            -
                    return (keccak256(fullData), timeBounds);
         | 
| 264 | 
            +
                    bytes32 dataHash = keccak256(bytes.concat(header, data));
         | 
| 265 | 
            +
                    return (dataHash, timeBounds);
         | 
| 224 266 | 
             
                }
         | 
| 225 267 |  | 
| 226 268 | 
             
                function formEmptyDataHash(uint256 afterDelayedMessagesRead)
         | 
| @@ -232,43 +274,120 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox | |
| 232 274 | 
             
                    return (keccak256(header), timeBounds);
         | 
| 233 275 | 
             
                }
         | 
| 234 276 |  | 
| 235 | 
            -
                function addSequencerL2BatchImpl( | 
| 277 | 
            +
                function addSequencerL2BatchImpl(
         | 
| 278 | 
            +
                    bytes32 dataHash,
         | 
| 279 | 
            +
                    uint256 afterDelayedMessagesRead,
         | 
| 280 | 
            +
                    uint256 calldataLengthPosted
         | 
| 281 | 
            +
                )
         | 
| 236 282 | 
             
                    internal
         | 
| 237 283 | 
             
                    returns (
         | 
| 284 | 
            +
                        uint256 seqMessageIndex,
         | 
| 238 285 | 
             
                        bytes32 beforeAcc,
         | 
| 239 286 | 
             
                        bytes32 delayedAcc,
         | 
| 240 287 | 
             
                        bytes32 acc
         | 
| 241 288 | 
             
                    )
         | 
| 242 289 | 
             
                {
         | 
| 243 290 | 
             
                    if (afterDelayedMessagesRead < totalDelayedMessagesRead) revert DelayedBackwards();
         | 
| 244 | 
            -
                    if (afterDelayedMessagesRead >  | 
| 291 | 
            +
                    if (afterDelayedMessagesRead > bridge.delayedMessageCount()) revert DelayedTooFar();
         | 
| 245 292 |  | 
| 246 | 
            -
                     | 
| 247 | 
            -
                         | 
| 248 | 
            -
             | 
| 249 | 
            -
                     | 
| 250 | 
            -
                        delayedAcc = delayedBridge.inboxAccs(afterDelayedMessagesRead - 1);
         | 
| 251 | 
            -
                    }
         | 
| 293 | 
            +
                    (seqMessageIndex, beforeAcc, delayedAcc, acc) = bridge.enqueueSequencerMessage(
         | 
| 294 | 
            +
                        dataHash,
         | 
| 295 | 
            +
                        afterDelayedMessagesRead
         | 
| 296 | 
            +
                    );
         | 
| 252 297 |  | 
| 253 | 
            -
                    acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc));
         | 
| 254 | 
            -
                    inboxAccs.push(acc);
         | 
| 255 298 | 
             
                    totalDelayedMessagesRead = afterDelayedMessagesRead;
         | 
| 299 | 
            +
             | 
| 300 | 
            +
                    if (calldataLengthPosted > 0) {
         | 
| 301 | 
            +
                        // this msg isn't included in the current sequencer batch, but instead added to
         | 
| 302 | 
            +
                        // the delayed messages queue that is yet to be included
         | 
| 303 | 
            +
                        address batchPoster = msg.sender;
         | 
| 304 | 
            +
                        bytes memory spendingReportMsg = abi.encodePacked(
         | 
| 305 | 
            +
                            block.timestamp,
         | 
| 306 | 
            +
                            batchPoster,
         | 
| 307 | 
            +
                            dataHash,
         | 
| 308 | 
            +
                            seqMessageIndex,
         | 
| 309 | 
            +
                            block.basefee
         | 
| 310 | 
            +
                        );
         | 
| 311 | 
            +
                        uint256 msgNum = bridge.submitBatchSpendingReport(
         | 
| 312 | 
            +
                            batchPoster,
         | 
| 313 | 
            +
                            keccak256(spendingReportMsg)
         | 
| 314 | 
            +
                        );
         | 
| 315 | 
            +
                        // this is the same event used by Inbox.sol after including a message to the delayed message accumulator
         | 
| 316 | 
            +
                        emit InboxMessageDelivered(msgNum, spendingReportMsg);
         | 
| 317 | 
            +
                    }
         | 
| 318 | 
            +
                }
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                function inboxAccs(uint256 index) external view override returns (bytes32) {
         | 
| 321 | 
            +
                    return bridge.sequencerInboxAccs(index);
         | 
| 256 322 | 
             
                }
         | 
| 257 323 |  | 
| 258 324 | 
             
                function batchCount() external view override returns (uint256) {
         | 
| 259 | 
            -
                    return  | 
| 325 | 
            +
                    return bridge.sequencerMessageCount();
         | 
| 260 326 | 
             
                }
         | 
| 261 327 |  | 
| 328 | 
            +
                /**
         | 
| 329 | 
            +
                 * @notice Set max delay for sequencer inbox
         | 
| 330 | 
            +
                 * @param maxTimeVariation_ the maximum time variation parameters
         | 
| 331 | 
            +
                 */
         | 
| 262 332 | 
             
                function setMaxTimeVariation(ISequencerInbox.MaxTimeVariation memory maxTimeVariation_)
         | 
| 263 333 | 
             
                    external
         | 
| 264 334 | 
             
                    override
         | 
| 335 | 
            +
                    onlyRollupOwner
         | 
| 265 336 | 
             
                {
         | 
| 266 | 
            -
                    if (msg.sender != rollup) revert NotRollup(msg.sender, rollup);
         | 
| 267 337 | 
             
                    maxTimeVariation = maxTimeVariation_;
         | 
| 338 | 
            +
                    emit OwnerFunctionCalled(0);
         | 
| 268 339 | 
             
                }
         | 
| 269 340 |  | 
| 270 | 
            -
                 | 
| 271 | 
            -
             | 
| 341 | 
            +
                /**
         | 
| 342 | 
            +
                 * @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox
         | 
| 343 | 
            +
                 * @param addr the address
         | 
| 344 | 
            +
                 * @param isBatchPoster_ if the specified address should be authorized as a batch poster
         | 
| 345 | 
            +
                 */
         | 
| 346 | 
            +
                function setIsBatchPoster(address addr, bool isBatchPoster_) external override onlyRollupOwner {
         | 
| 272 347 | 
             
                    isBatchPoster[addr] = isBatchPoster_;
         | 
| 348 | 
            +
                    emit OwnerFunctionCalled(1);
         | 
| 349 | 
            +
                }
         | 
| 350 | 
            +
             | 
| 351 | 
            +
                /**
         | 
| 352 | 
            +
                 * @notice Makes Data Availability Service keyset valid
         | 
| 353 | 
            +
                 * @param keysetBytes bytes of the serialized keyset
         | 
| 354 | 
            +
                 */
         | 
| 355 | 
            +
                function setValidKeyset(bytes calldata keysetBytes) external override onlyRollupOwner {
         | 
| 356 | 
            +
                    uint256 ksWord = uint256(keccak256(bytes.concat(hex"fe", keccak256(keysetBytes))));
         | 
| 357 | 
            +
                    bytes32 ksHash = bytes32(ksWord ^ (1 << 255));
         | 
| 358 | 
            +
                    require(keysetBytes.length < 64 * 1024, "keyset is too large");
         | 
| 359 | 
            +
             | 
| 360 | 
            +
                    if (dasKeySetInfo[ksHash].isValidKeyset) revert AlreadyValidDASKeyset(ksHash);
         | 
| 361 | 
            +
                    dasKeySetInfo[ksHash] = DasKeySetInfo({
         | 
| 362 | 
            +
                        isValidKeyset: true,
         | 
| 363 | 
            +
                        creationBlock: uint64(block.number)
         | 
| 364 | 
            +
                    });
         | 
| 365 | 
            +
                    emit SetValidKeyset(ksHash, keysetBytes);
         | 
| 366 | 
            +
                    emit OwnerFunctionCalled(2);
         | 
| 367 | 
            +
                }
         | 
| 368 | 
            +
             | 
| 369 | 
            +
                /**
         | 
| 370 | 
            +
                 * @notice Invalidates a Data Availability Service keyset
         | 
| 371 | 
            +
                 * @param ksHash hash of the keyset
         | 
| 372 | 
            +
                 */
         | 
| 373 | 
            +
                function invalidateKeysetHash(bytes32 ksHash) external override onlyRollupOwner {
         | 
| 374 | 
            +
                    if (!dasKeySetInfo[ksHash].isValidKeyset) revert NoSuchKeyset(ksHash);
         | 
| 375 | 
            +
                    // we don't delete the block creation value since its used to fetch the SetValidKeyset
         | 
| 376 | 
            +
                    // event efficiently. The event provides the hash preimage of the key.
         | 
| 377 | 
            +
                    // this is still needed when syncing the chain after a keyset is invalidated.
         | 
| 378 | 
            +
                    dasKeySetInfo[ksHash].isValidKeyset = false;
         | 
| 379 | 
            +
                    emit InvalidateKeyset(ksHash);
         | 
| 380 | 
            +
                    emit OwnerFunctionCalled(3);
         | 
| 381 | 
            +
                }
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                function isValidKeysetHash(bytes32 ksHash) external view returns (bool) {
         | 
| 384 | 
            +
                    return dasKeySetInfo[ksHash].isValidKeyset;
         | 
| 385 | 
            +
                }
         | 
| 386 | 
            +
             | 
| 387 | 
            +
                /// @notice the creation block is intended to still be available after a keyset is deleted
         | 
| 388 | 
            +
                function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256) {
         | 
| 389 | 
            +
                    DasKeySetInfo memory ksInfo = dasKeySetInfo[ksHash];
         | 
| 390 | 
            +
                    if (ksInfo.creationBlock == 0) revert NoSuchKeyset(ksHash);
         | 
| 391 | 
            +
                    return uint256(ksInfo.creationBlock);
         | 
| 273 392 | 
             
                }
         | 
| 274 393 | 
             
            }
         | 
| @@ -61,14 +61,12 @@ library ChallengeLib { | |
| 61 61 | 
             
                    ValueArray memory valuesArray = ValueArray({inner: startingValues});
         | 
| 62 62 | 
             
                    ValueStack memory values = ValueStack({proved: valuesArray, remainingHash: 0});
         | 
| 63 63 | 
             
                    ValueStack memory internalStack;
         | 
| 64 | 
            -
                    PcStack memory blocks;
         | 
| 65 64 | 
             
                    StackFrameWindow memory frameStack;
         | 
| 66 65 |  | 
| 67 66 | 
             
                    Machine memory mach = Machine({
         | 
| 68 67 | 
             
                        status: MachineStatus.RUNNING,
         | 
| 69 68 | 
             
                        valueStack: values,
         | 
| 70 69 | 
             
                        internalStack: internalStack,
         | 
| 71 | 
            -
                        blockStack: blocks,
         | 
| 72 70 | 
             
                        frameStack: frameStack,
         | 
| 73 71 | 
             
                        globalStateHash: globalStateHash,
         | 
| 74 72 | 
             
                        moduleIdx: 0,
         | 
| @@ -33,7 +33,7 @@ contract ChallengeManager is DelegateCallAware, IChallengeManager { | |
| 33 33 | 
             
                IChallengeResultReceiver public resultReceiver;
         | 
| 34 34 |  | 
| 35 35 | 
             
                ISequencerInbox public sequencerInbox;
         | 
| 36 | 
            -
                IBridge public  | 
| 36 | 
            +
                IBridge public bridge;
         | 
| 37 37 | 
             
                IOneStepProofEntry public osp;
         | 
| 38 38 |  | 
| 39 39 | 
             
                function challengeInfo(uint64 challengeIndex)
         | 
| @@ -99,14 +99,14 @@ contract ChallengeManager is DelegateCallAware, IChallengeManager { | |
| 99 99 | 
             
                function initialize(
         | 
| 100 100 | 
             
                    IChallengeResultReceiver resultReceiver_,
         | 
| 101 101 | 
             
                    ISequencerInbox sequencerInbox_,
         | 
| 102 | 
            -
                    IBridge  | 
| 102 | 
            +
                    IBridge bridge_,
         | 
| 103 103 | 
             
                    IOneStepProofEntry osp_
         | 
| 104 104 | 
             
                ) external override onlyDelegated {
         | 
| 105 105 | 
             
                    require(address(resultReceiver) == address(0), "ALREADY_INIT");
         | 
| 106 106 | 
             
                    require(address(resultReceiver_) != address(0), "NO_RESULT_RECEIVER");
         | 
| 107 107 | 
             
                    resultReceiver = resultReceiver_;
         | 
| 108 108 | 
             
                    sequencerInbox = sequencerInbox_;
         | 
| 109 | 
            -
                     | 
| 109 | 
            +
                    bridge = bridge_;
         | 
| 110 110 | 
             
                    osp = osp_;
         | 
| 111 111 | 
             
                }
         | 
| 112 112 |  | 
| @@ -254,11 +254,7 @@ contract ChallengeManager is DelegateCallAware, IChallengeManager { | |
| 254 254 | 
             
                    }
         | 
| 255 255 |  | 
| 256 256 | 
             
                    bytes32 afterHash = osp.proveOneStep(
         | 
| 257 | 
            -
                        ExecutionContext({
         | 
| 258 | 
            -
                            maxInboxMessagesRead: challenge.maxInboxMessages,
         | 
| 259 | 
            -
                            sequencerInbox: sequencerInbox,
         | 
| 260 | 
            -
                            delayedBridge: delayedBridge
         | 
| 261 | 
            -
                        }),
         | 
| 257 | 
            +
                        ExecutionContext({maxInboxMessagesRead: challenge.maxInboxMessages, bridge: bridge}),
         | 
| 262 258 | 
             
                        challengeStart,
         | 
| 263 259 | 
             
                        selection.oldSegments[selection.challengePosition],
         | 
| 264 260 | 
             
                        proof
         | 
    
        package/src/libraries/Error.sol
    CHANGED
    
    | @@ -36,3 +36,116 @@ error NotContract(address addr); | |
| 36 36 | 
             
            /// @param actualLength The length of the merkle proof provided
         | 
| 37 37 | 
             
            /// @param maxProofLength The max length a merkle proof can have
         | 
| 38 38 | 
             
            error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength);
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            /// @dev Thrown when an un-authorized address tries to access an admin function
         | 
| 41 | 
            +
            /// @param sender The un-authorized sender
         | 
| 42 | 
            +
            /// @param rollup The rollup, which would be authorized
         | 
| 43 | 
            +
            /// @param owner The rollup's owner, which would be authorized
         | 
| 44 | 
            +
            error NotRollupOrOwner(address sender, address rollup, address owner);
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            // Bridge Errors
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            /// @dev Thrown when an un-authorized address tries to access an only-inbox function
         | 
| 49 | 
            +
            /// @param sender The un-authorized sender
         | 
| 50 | 
            +
            error NotDelayedInbox(address sender);
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function
         | 
| 53 | 
            +
            /// @param sender The un-authorized sender
         | 
| 54 | 
            +
            error NotSequencerInbox(address sender);
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            /// @dev Thrown when an un-authorized address tries to access an only-outbox function
         | 
| 57 | 
            +
            /// @param sender The un-authorized sender
         | 
| 58 | 
            +
            error NotOutbox(address sender);
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            /// @dev the provided outbox address isn't valid
         | 
| 61 | 
            +
            /// @param outbox address of outbox being set
         | 
| 62 | 
            +
            error InvalidOutboxSet(address outbox);
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            // Inbox Errors
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            /// @dev The contract is paused, so cannot be paused
         | 
| 67 | 
            +
            error AlreadyPaused();
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            /// @dev The contract is unpaused, so cannot be unpaused
         | 
| 70 | 
            +
            error AlreadyUnpaused();
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            /// @dev The contract is paused
         | 
| 73 | 
            +
            error Paused();
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            /// @dev msg.value sent to the inbox isn't high enough
         | 
| 76 | 
            +
            error InsufficientValue(uint256 expected, uint256 actual);
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            /// @dev submission cost provided isn't enough to create retryable ticket
         | 
| 79 | 
            +
            error InsufficientSubmissionCost(uint256 expected, uint256 actual);
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            /// @dev address not allowed to interact with the given contract
         | 
| 82 | 
            +
            error NotAllowedOrigin(address origin);
         | 
| 83 | 
            +
             | 
| 84 | 
            +
            /// @dev used to convey retryable tx data in eth calls without requiring a tx trace
         | 
| 85 | 
            +
            /// this follows a pattern similar to EIP-3668 where reverts surface call information
         | 
| 86 | 
            +
            error RetryableData(
         | 
| 87 | 
            +
                address from,
         | 
| 88 | 
            +
                address to,
         | 
| 89 | 
            +
                uint256 l2CallValue,
         | 
| 90 | 
            +
                uint256 deposit,
         | 
| 91 | 
            +
                uint256 maxSubmissionCost,
         | 
| 92 | 
            +
                address excessFeeRefundAddress,
         | 
| 93 | 
            +
                address callValueRefundAddress,
         | 
| 94 | 
            +
                uint256 gasLimit,
         | 
| 95 | 
            +
                uint256 maxFeePerGas,
         | 
| 96 | 
            +
                bytes data
         | 
| 97 | 
            +
            );
         | 
| 98 | 
            +
             | 
| 99 | 
            +
            // Outbox Errors
         | 
| 100 | 
            +
             | 
| 101 | 
            +
            /// @dev The provided proof was too long
         | 
| 102 | 
            +
            /// @param proofLength The length of the too-long proof
         | 
| 103 | 
            +
            error ProofTooLong(uint256 proofLength);
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            /// @dev The output index was greater than the maximum
         | 
| 106 | 
            +
            /// @param index The output index
         | 
| 107 | 
            +
            /// @param maxIndex The max the index could be
         | 
| 108 | 
            +
            error PathNotMinimal(uint256 index, uint256 maxIndex);
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            /// @dev The calculated root does not exist
         | 
| 111 | 
            +
            /// @param root The calculated root
         | 
| 112 | 
            +
            error UnknownRoot(bytes32 root);
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            /// @dev The record has already been spent
         | 
| 115 | 
            +
            /// @param index The index of the spent record
         | 
| 116 | 
            +
            error AlreadySpent(uint256 index);
         | 
| 117 | 
            +
             | 
| 118 | 
            +
            /// @dev A call to the bridge failed with no return data
         | 
| 119 | 
            +
            error BridgeCallFailed();
         | 
| 120 | 
            +
             | 
| 121 | 
            +
            // Sequencer Inbox Errors
         | 
| 122 | 
            +
             | 
| 123 | 
            +
            /// @dev Thrown when someone attempts to read fewer messages than have already been read
         | 
| 124 | 
            +
            error DelayedBackwards();
         | 
| 125 | 
            +
             | 
| 126 | 
            +
            /// @dev Thrown when someone attempts to read more messages than exist
         | 
| 127 | 
            +
            error DelayedTooFar();
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            /// @dev Force include can only read messages more blocks old than the delay period
         | 
| 130 | 
            +
            error ForceIncludeBlockTooSoon();
         | 
| 131 | 
            +
             | 
| 132 | 
            +
            /// @dev Force include can only read messages more seconds old than the delay period
         | 
| 133 | 
            +
            error ForceIncludeTimeTooSoon();
         | 
| 134 | 
            +
             | 
| 135 | 
            +
            /// @dev The message provided did not match the hash in the delayed inbox
         | 
| 136 | 
            +
            error IncorrectMessagePreimage();
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            /// @dev This can only be called by the batch poster
         | 
| 139 | 
            +
            error NotBatchPoster();
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            /// @dev The sequence number provided to this message was inconsistent with the number of batches already included
         | 
| 142 | 
            +
            error BadSequencerNumber(uint256 stored, uint256 received);
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            /// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox
         | 
| 145 | 
            +
            error DataNotAuthenticated();
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            /// @dev Tried to create an already valid Data Availability Service keyset
         | 
| 148 | 
            +
            error AlreadyValidDASKeyset(bytes32);
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset
         | 
| 151 | 
            +
            error NoSuchKeyset(bytes32);
         | 
| @@ -2,7 +2,8 @@ | |
| 2 2 | 
             
            // For license information, see https://github.com/nitro/blob/master/LICENSE
         | 
| 3 3 | 
             
            // SPDX-License-Identifier: BUSL-1.1
         | 
| 4 4 |  | 
| 5 | 
            -
             | 
| 5 | 
            +
            // solhint-disable-next-line compiler-version
         | 
| 6 | 
            +
            pragma solidity >=0.6.9 <0.9.0;
         | 
| 6 7 |  | 
| 7 8 | 
             
            interface IGasRefunder {
         | 
| 8 9 | 
             
                function onGasSpent(
         | 
| @@ -13,23 +14,23 @@ interface IGasRefunder { | |
| 13 14 | 
             
            }
         | 
| 14 15 |  | 
| 15 16 | 
             
            abstract contract GasRefundEnabled {
         | 
| 16 | 
            -
                 | 
| 17 | 
            +
                /// @dev this refunds the sender for execution costs of the tx
         | 
| 18 | 
            +
                /// calldata costs are only refunded if `msg.sender == tx.origin` to guarantee the value refunded relates to charging
         | 
| 19 | 
            +
                /// for the `tx.input`. this avoids a possible attack where you generate large calldata from a contract and get over-refunded
         | 
| 20 | 
            +
                modifier refundsGas(IGasRefunder gasRefunder) {
         | 
| 17 21 | 
             
                    uint256 startGasLeft = gasleft();
         | 
| 18 22 | 
             
                    _;
         | 
| 19 23 | 
             
                    if (address(gasRefunder) != address(0)) {
         | 
| 20 | 
            -
                        uint256 calldataSize;
         | 
| 21 | 
            -
                         | 
| 22 | 
            -
             | 
| 24 | 
            +
                        uint256 calldataSize = 0;
         | 
| 25 | 
            +
                        // if triggered in a contract call, the spender may be overrefunded by appending dummy data to the call
         | 
| 26 | 
            +
                        // so we check if it is a top level call, which would mean the sender paid calldata as part of tx.input
         | 
| 27 | 
            +
                        // solhint-disable-next-line avoid-tx-origin
         | 
| 28 | 
            +
                        if (msg.sender == tx.origin) {
         | 
| 29 | 
            +
                            assembly {
         | 
| 30 | 
            +
                                calldataSize := calldatasize()
         | 
| 31 | 
            +
                            }
         | 
| 23 32 | 
             
                        }
         | 
| 24 | 
            -
                        gasRefunder.onGasSpent( | 
| 25 | 
            -
                    }
         | 
| 26 | 
            -
                }
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                modifier refundsGasNoCalldata(IGasRefunder gasRefunder, address payable spender) {
         | 
| 29 | 
            -
                    uint256 startGasLeft = gasleft();
         | 
| 30 | 
            -
                    _;
         | 
| 31 | 
            -
                    if (address(gasRefunder) != address(0)) {
         | 
| 32 | 
            -
                        gasRefunder.onGasSpent(spender, startGasLeft - gasleft(), 0);
         | 
| 33 | 
            +
                        gasRefunder.onGasSpent(payable(msg.sender), startGasLeft - gasleft(), calldataSize);
         | 
| 33 34 | 
             
                    }
         | 
| 34 35 | 
             
                }
         | 
| 35 36 | 
             
            }
         | 
| @@ -34,10 +34,19 @@ library MerkleLib { | |
| 34 34 | 
             
                    if (proofItems > 256) revert MerkleProofTooLong(proofItems, 256);
         | 
| 35 35 | 
             
                    bytes32 h = item;
         | 
| 36 36 | 
             
                    for (uint256 i = 0; i < proofItems; i++) {
         | 
| 37 | 
            +
                        bytes32 node = nodes[i];
         | 
| 37 38 | 
             
                        if (route % 2 == 0) {
         | 
| 38 | 
            -
                             | 
| 39 | 
            +
                            assembly {
         | 
| 40 | 
            +
                                mstore(0x00, h)
         | 
| 41 | 
            +
                                mstore(0x20, node)
         | 
| 42 | 
            +
                                h := keccak256(0x00, 0x40)
         | 
| 43 | 
            +
                            }
         | 
| 39 44 | 
             
                        } else {
         | 
| 40 | 
            -
                             | 
| 45 | 
            +
                            assembly {
         | 
| 46 | 
            +
                                mstore(0x00, node)
         | 
| 47 | 
            +
                                mstore(0x20, h)
         | 
| 48 | 
            +
                                h := keccak256(0x00, 0x40)
         | 
| 49 | 
            +
                            }
         | 
| 41 50 | 
             
                        }
         | 
| 42 51 | 
             
                        route /= 2;
         | 
| 43 52 | 
             
                    }
         | 
| @@ -8,6 +8,7 @@ uint8 constant L2_MSG = 3; | |
| 8 8 | 
             
            uint8 constant L1MessageType_L2FundedByL1 = 7;
         | 
| 9 9 | 
             
            uint8 constant L1MessageType_submitRetryableTx = 9;
         | 
| 10 10 | 
             
            uint8 constant L1MessageType_ethDeposit = 12;
         | 
| 11 | 
            +
            uint8 constant L1MessageType_batchPostingReport = 13;
         | 
| 11 12 | 
             
            uint8 constant L2MessageType_unsignedEOATx = 0;
         | 
| 12 13 | 
             
            uint8 constant L2MessageType_unsignedContractTx = 1;
         | 
| 13 14 |  |