@arbitrum/nitro-contracts 1.0.0-beta.4 → 1.0.0-beta.7
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 +2 -1
- package/src/bridge/Bridge.sol +127 -32
- package/src/bridge/IBridge.sol +40 -6
- package/src/bridge/{IMessageProvider.sol → IDelayedMessageProvider.sol} +4 -1
- package/src/bridge/IInbox.sol +23 -2
- package/src/bridge/IOwnable.sol +9 -0
- package/src/bridge/ISequencerInbox.sol +36 -9
- package/src/bridge/Inbox.sol +131 -34
- package/src/bridge/Outbox.sol +134 -31
- package/src/bridge/SequencerInbox.sol +159 -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 +6 -0
- package/src/libraries/IGasRefunder.sol +13 -13
- package/src/libraries/MerkleLib.sol +11 -2
- package/src/libraries/MessageTypes.sol +1 -0
- package/src/mocks/BridgeStub.sol +67 -21
- package/src/mocks/SequencerInboxStub.sol +10 -8
- package/src/mocks/Simple.sol +8 -0
- package/src/node-interface/NodeInterface.sol +32 -5
- 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 +9 -18
- package/src/precompiles/ArbOwner.sol +18 -15
- package/src/precompiles/ArbRetryableTx.sol +13 -1
- package/src/precompiles/ArbSys.sol +15 -2
- 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 +30 -34
- package/src/rollup/RollupCore.sol +15 -7
- package/src/rollup/RollupCreator.sol +21 -11
- package/src/rollup/{RollupEventBridge.sol → RollupEventInbox.sol} +10 -10
- package/src/rollup/RollupLib.sol +20 -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/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 +223 -0
- package/src/test-helpers/OutboxWithoutOptTester.sol +188 -0
- package/src/test-helpers/RollupMock.sol +21 -0
- package/src/state/PcStack.sol +0 -32
@@ -0,0 +1,223 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.4;
|
6
|
+
|
7
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
8
|
+
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
|
9
|
+
|
10
|
+
import "../bridge/IBridge.sol";
|
11
|
+
import "../bridge/Messages.sol";
|
12
|
+
import "../libraries/DelegateCallAware.sol";
|
13
|
+
|
14
|
+
/**
|
15
|
+
* @title Staging ground for incoming and outgoing messages
|
16
|
+
* @notice Holds the inbox accumulator for delayed messages, and is the ETH escrow
|
17
|
+
* for value sent with these messages.
|
18
|
+
* Since the escrow is held here, this contract also contains a list of allowed
|
19
|
+
* outboxes that can make calls from here and withdraw this escrow.
|
20
|
+
*/
|
21
|
+
contract BridgeTester is Initializable, DelegateCallAware, IBridge {
|
22
|
+
using AddressUpgradeable for address;
|
23
|
+
|
24
|
+
struct InOutInfo {
|
25
|
+
uint256 index;
|
26
|
+
bool allowed;
|
27
|
+
}
|
28
|
+
|
29
|
+
mapping(address => InOutInfo) private allowedInboxesMap;
|
30
|
+
mapping(address => InOutInfo) private allowedOutboxesMap;
|
31
|
+
|
32
|
+
address[] public allowedDelayedInboxList;
|
33
|
+
address[] public allowedOutboxList;
|
34
|
+
|
35
|
+
address private _activeOutbox;
|
36
|
+
|
37
|
+
IOwnable public rollup;
|
38
|
+
address public sequencerInbox;
|
39
|
+
|
40
|
+
modifier onlyRollupOrOwner() {
|
41
|
+
if (msg.sender != address(rollup)) {
|
42
|
+
address rollupOwner = rollup.owner();
|
43
|
+
if (msg.sender != rollupOwner) {
|
44
|
+
revert NotRollupOrOwner(msg.sender, address(rollup), rollupOwner);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
_;
|
48
|
+
}
|
49
|
+
|
50
|
+
function setSequencerInbox(address _sequencerInbox) external override onlyRollupOrOwner {
|
51
|
+
sequencerInbox = _sequencerInbox;
|
52
|
+
emit SequencerInboxUpdated(_sequencerInbox);
|
53
|
+
}
|
54
|
+
|
55
|
+
/// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
|
56
|
+
bytes32[] public override delayedInboxAccs;
|
57
|
+
|
58
|
+
bytes32[] public override sequencerInboxAccs;
|
59
|
+
|
60
|
+
address private constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max);
|
61
|
+
|
62
|
+
function initialize(IOwnable rollup_) external initializer {
|
63
|
+
_activeOutbox = EMPTY_ACTIVEOUTBOX;
|
64
|
+
rollup = rollup_;
|
65
|
+
}
|
66
|
+
|
67
|
+
function activeOutbox() public view returns (address) {
|
68
|
+
if (_activeOutbox == EMPTY_ACTIVEOUTBOX) return address(uint160(0));
|
69
|
+
return _activeOutbox;
|
70
|
+
}
|
71
|
+
|
72
|
+
function allowedDelayedInboxes(address inbox) external view override returns (bool) {
|
73
|
+
return allowedInboxesMap[inbox].allowed;
|
74
|
+
}
|
75
|
+
|
76
|
+
function allowedOutboxes(address outbox) external view override returns (bool) {
|
77
|
+
return allowedOutboxesMap[outbox].allowed;
|
78
|
+
}
|
79
|
+
|
80
|
+
function enqueueSequencerMessage(bytes32 dataHash, uint256 afterDelayedMessagesRead)
|
81
|
+
external
|
82
|
+
returns (
|
83
|
+
uint256 seqMessageIndex,
|
84
|
+
bytes32 beforeAcc,
|
85
|
+
bytes32 delayedAcc,
|
86
|
+
bytes32 acc
|
87
|
+
)
|
88
|
+
{
|
89
|
+
// TODO: implement stub logic
|
90
|
+
}
|
91
|
+
|
92
|
+
function submitBatchSpendingReport(address batchPoster, bytes32 dataHash)
|
93
|
+
external
|
94
|
+
returns (uint256)
|
95
|
+
{
|
96
|
+
// TODO: implement stub
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* @dev Enqueue a message in the delayed inbox accumulator.
|
101
|
+
* These messages are later sequenced in the SequencerInbox, either by the sequencer as
|
102
|
+
* part of a normal batch, or by force inclusion.
|
103
|
+
*/
|
104
|
+
function enqueueDelayedMessage(
|
105
|
+
uint8 kind,
|
106
|
+
address sender,
|
107
|
+
bytes32 messageDataHash
|
108
|
+
) external payable override returns (uint256) {
|
109
|
+
if (!allowedInboxesMap[msg.sender].allowed) revert NotDelayedInbox(msg.sender);
|
110
|
+
return
|
111
|
+
addMessageToDelayedAccumulator(
|
112
|
+
kind,
|
113
|
+
sender,
|
114
|
+
uint64(block.number),
|
115
|
+
uint64(block.timestamp), // solhint-disable-line not-rely-on-time
|
116
|
+
block.basefee,
|
117
|
+
messageDataHash
|
118
|
+
);
|
119
|
+
}
|
120
|
+
|
121
|
+
function addMessageToDelayedAccumulator(
|
122
|
+
uint8 kind,
|
123
|
+
address sender,
|
124
|
+
uint64 blockNumber,
|
125
|
+
uint64 blockTimestamp,
|
126
|
+
uint256 baseFeeL1,
|
127
|
+
bytes32 messageDataHash
|
128
|
+
) internal returns (uint256) {
|
129
|
+
uint256 count = delayedInboxAccs.length;
|
130
|
+
bytes32 messageHash = Messages.messageHash(
|
131
|
+
kind,
|
132
|
+
sender,
|
133
|
+
blockNumber,
|
134
|
+
blockTimestamp,
|
135
|
+
count,
|
136
|
+
baseFeeL1,
|
137
|
+
messageDataHash
|
138
|
+
);
|
139
|
+
bytes32 prevAcc = 0;
|
140
|
+
if (count > 0) {
|
141
|
+
prevAcc = delayedInboxAccs[count - 1];
|
142
|
+
}
|
143
|
+
delayedInboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash));
|
144
|
+
emit MessageDelivered(
|
145
|
+
count,
|
146
|
+
prevAcc,
|
147
|
+
msg.sender,
|
148
|
+
kind,
|
149
|
+
sender,
|
150
|
+
messageDataHash,
|
151
|
+
baseFeeL1,
|
152
|
+
blockTimestamp
|
153
|
+
);
|
154
|
+
return count;
|
155
|
+
}
|
156
|
+
|
157
|
+
function executeCall(
|
158
|
+
address to,
|
159
|
+
uint256 value,
|
160
|
+
bytes calldata data
|
161
|
+
) external override returns (bool success, bytes memory returnData) {
|
162
|
+
if (!allowedOutboxesMap[msg.sender].allowed) revert NotOutbox(msg.sender);
|
163
|
+
if (data.length > 0 && !to.isContract()) revert NotContract(to);
|
164
|
+
address prevOutbox = _activeOutbox;
|
165
|
+
_activeOutbox = msg.sender;
|
166
|
+
// We set and reset active outbox around external call so activeOutbox remains valid during call
|
167
|
+
|
168
|
+
// We use a low level call here since we want to bubble up whether it succeeded or failed to the caller
|
169
|
+
// rather than reverting on failure as well as allow contract and non-contract calls
|
170
|
+
// solhint-disable-next-line avoid-low-level-calls
|
171
|
+
(success, returnData) = to.call{value: value}(data);
|
172
|
+
_activeOutbox = prevOutbox;
|
173
|
+
emit BridgeCallTriggered(msg.sender, to, value, data);
|
174
|
+
}
|
175
|
+
|
176
|
+
function setDelayedInbox(address inbox, bool enabled) external override onlyRollupOrOwner {
|
177
|
+
InOutInfo storage info = allowedInboxesMap[inbox];
|
178
|
+
bool alreadyEnabled = info.allowed;
|
179
|
+
emit InboxToggle(inbox, enabled);
|
180
|
+
if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
|
181
|
+
return;
|
182
|
+
}
|
183
|
+
if (enabled) {
|
184
|
+
allowedInboxesMap[inbox] = InOutInfo(allowedDelayedInboxList.length, true);
|
185
|
+
allowedDelayedInboxList.push(inbox);
|
186
|
+
} else {
|
187
|
+
allowedDelayedInboxList[info.index] = allowedDelayedInboxList[
|
188
|
+
allowedDelayedInboxList.length - 1
|
189
|
+
];
|
190
|
+
allowedInboxesMap[allowedDelayedInboxList[info.index]].index = info.index;
|
191
|
+
allowedDelayedInboxList.pop();
|
192
|
+
delete allowedInboxesMap[inbox];
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
function setOutbox(address outbox, bool enabled) external override onlyRollupOrOwner {
|
197
|
+
InOutInfo storage info = allowedOutboxesMap[outbox];
|
198
|
+
bool alreadyEnabled = info.allowed;
|
199
|
+
emit OutboxToggle(outbox, enabled);
|
200
|
+
if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
|
201
|
+
return;
|
202
|
+
}
|
203
|
+
if (enabled) {
|
204
|
+
allowedOutboxesMap[outbox] = InOutInfo(allowedOutboxList.length, true);
|
205
|
+
allowedOutboxList.push(outbox);
|
206
|
+
} else {
|
207
|
+
allowedOutboxList[info.index] = allowedOutboxList[allowedOutboxList.length - 1];
|
208
|
+
allowedOutboxesMap[allowedOutboxList[info.index]].index = info.index;
|
209
|
+
allowedOutboxList.pop();
|
210
|
+
delete allowedOutboxesMap[outbox];
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
function delayedMessageCount() external view override returns (uint256) {
|
215
|
+
return delayedInboxAccs.length;
|
216
|
+
}
|
217
|
+
|
218
|
+
function sequencerMessageCount() external view override returns (uint256) {
|
219
|
+
return sequencerInboxAccs.length;
|
220
|
+
}
|
221
|
+
|
222
|
+
receive() external payable {}
|
223
|
+
}
|
@@ -0,0 +1,188 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.4;
|
6
|
+
|
7
|
+
import "../bridge/IBridge.sol";
|
8
|
+
import "../bridge/IOutbox.sol";
|
9
|
+
import "../libraries/MerkleLib.sol";
|
10
|
+
import "../libraries/DelegateCallAware.sol";
|
11
|
+
|
12
|
+
contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
|
13
|
+
address public rollup; // the rollup contract
|
14
|
+
IBridge public bridge; // the bridge contract
|
15
|
+
|
16
|
+
mapping(uint256 => bool) public spent; // maps leaf number => if spent
|
17
|
+
mapping(bytes32 => bytes32) public roots; // maps root hashes => L2 block hash
|
18
|
+
|
19
|
+
struct L2ToL1Context {
|
20
|
+
uint128 l2Block;
|
21
|
+
uint128 l1Block;
|
22
|
+
uint128 timestamp;
|
23
|
+
bytes32 outputId;
|
24
|
+
address sender;
|
25
|
+
}
|
26
|
+
// Note, these variables are set and then wiped during a single transaction.
|
27
|
+
// Therefore their values don't need to be maintained, and their slots will
|
28
|
+
// be empty outside of transactions
|
29
|
+
L2ToL1Context internal context;
|
30
|
+
uint128 public constant OUTBOX_VERSION = 2;
|
31
|
+
|
32
|
+
function initialize(IBridge _bridge) external {
|
33
|
+
if (address(bridge) != address(0)) revert AlreadyInit();
|
34
|
+
bridge = _bridge;
|
35
|
+
rollup = address(_bridge.rollup());
|
36
|
+
}
|
37
|
+
|
38
|
+
function updateSendRoot(bytes32 root, bytes32 l2BlockHash) external override {
|
39
|
+
//if (msg.sender != rollup) revert NotRollup(msg.sender, rollup); //test only!!!
|
40
|
+
roots[root] = l2BlockHash;
|
41
|
+
emit SendRootUpdated(root, l2BlockHash);
|
42
|
+
}
|
43
|
+
|
44
|
+
/// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account
|
45
|
+
/// When the return value is zero, that means this is a system message
|
46
|
+
/// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies
|
47
|
+
function l2ToL1Sender() external view override returns (address) {
|
48
|
+
return context.sender;
|
49
|
+
}
|
50
|
+
|
51
|
+
function l2ToL1Block() external view override returns (uint256) {
|
52
|
+
return uint256(context.l2Block);
|
53
|
+
}
|
54
|
+
|
55
|
+
function l2ToL1EthBlock() external view override returns (uint256) {
|
56
|
+
return uint256(context.l1Block);
|
57
|
+
}
|
58
|
+
|
59
|
+
function l2ToL1Timestamp() external view override returns (uint256) {
|
60
|
+
return uint256(context.timestamp);
|
61
|
+
}
|
62
|
+
|
63
|
+
// @deprecated batch number is now always 0
|
64
|
+
function l2ToL1BatchNum() external pure override returns (uint256) {
|
65
|
+
return 0;
|
66
|
+
}
|
67
|
+
|
68
|
+
function l2ToL1OutputId() external view override returns (bytes32) {
|
69
|
+
return context.outputId;
|
70
|
+
}
|
71
|
+
|
72
|
+
/**
|
73
|
+
* @notice Executes a messages in an Outbox entry.
|
74
|
+
* @dev Reverts if dispute period hasn't expired, since the outbox entry
|
75
|
+
* is only created once the rollup confirms the respective assertion.
|
76
|
+
* @param proof Merkle proof of message inclusion in send root
|
77
|
+
* @param index Merkle path to message
|
78
|
+
* @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
|
79
|
+
* @param to destination address for L1 contract call
|
80
|
+
* @param l2Block l2 block number at which sendTxToL1 call was made
|
81
|
+
* @param l1Block l1 block number at which sendTxToL1 call was made
|
82
|
+
* @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made
|
83
|
+
* @param value wei in L1 message
|
84
|
+
* @param data abi-encoded L1 message data
|
85
|
+
*/
|
86
|
+
function executeTransaction(
|
87
|
+
bytes32[] calldata proof,
|
88
|
+
uint256 index,
|
89
|
+
address l2Sender,
|
90
|
+
address to,
|
91
|
+
uint256 l2Block,
|
92
|
+
uint256 l1Block,
|
93
|
+
uint256 l2Timestamp,
|
94
|
+
uint256 value,
|
95
|
+
bytes calldata data
|
96
|
+
) external virtual {
|
97
|
+
bytes32 outputId;
|
98
|
+
{
|
99
|
+
bytes32 userTx = calculateItemHash(
|
100
|
+
l2Sender,
|
101
|
+
to,
|
102
|
+
l2Block,
|
103
|
+
l1Block,
|
104
|
+
l2Timestamp,
|
105
|
+
value,
|
106
|
+
data
|
107
|
+
);
|
108
|
+
|
109
|
+
outputId = recordOutputAsSpent(proof, index, userTx);
|
110
|
+
emit OutBoxTransactionExecuted(to, l2Sender, 0, index);
|
111
|
+
}
|
112
|
+
|
113
|
+
// we temporarily store the previous values so the outbox can naturally
|
114
|
+
// unwind itself when there are nested calls to `executeTransaction`
|
115
|
+
L2ToL1Context memory prevContext = context;
|
116
|
+
|
117
|
+
context = L2ToL1Context({
|
118
|
+
sender: l2Sender,
|
119
|
+
l2Block: uint128(l2Block),
|
120
|
+
l1Block: uint128(l1Block),
|
121
|
+
timestamp: uint128(l2Timestamp),
|
122
|
+
outputId: outputId
|
123
|
+
});
|
124
|
+
|
125
|
+
// set and reset vars around execution so they remain valid during call
|
126
|
+
executeBridgeCall(to, value, data);
|
127
|
+
|
128
|
+
context = prevContext;
|
129
|
+
}
|
130
|
+
|
131
|
+
function recordOutputAsSpent(
|
132
|
+
bytes32[] memory proof,
|
133
|
+
uint256 index,
|
134
|
+
bytes32 item
|
135
|
+
) internal returns (bytes32) {
|
136
|
+
if (proof.length >= 256) revert ProofTooLong(proof.length);
|
137
|
+
if (index >= 2**proof.length) revert PathNotMinimal(index, 2**proof.length);
|
138
|
+
|
139
|
+
// Hash the leaf an extra time to prove it's a leaf
|
140
|
+
bytes32 calcRoot = calculateMerkleRoot(proof, index, item);
|
141
|
+
if (roots[calcRoot] == bytes32(0)) revert UnknownRoot(calcRoot);
|
142
|
+
|
143
|
+
if (spent[index]) revert AlreadySpent(index);
|
144
|
+
spent[index] = true;
|
145
|
+
|
146
|
+
return bytes32(index);
|
147
|
+
}
|
148
|
+
|
149
|
+
function executeBridgeCall(
|
150
|
+
address to,
|
151
|
+
uint256 value,
|
152
|
+
bytes memory data
|
153
|
+
) internal {
|
154
|
+
(bool success, bytes memory returndata) = bridge.executeCall(to, value, data);
|
155
|
+
if (!success) {
|
156
|
+
if (returndata.length > 0) {
|
157
|
+
// solhint-disable-next-line no-inline-assembly
|
158
|
+
assembly {
|
159
|
+
let returndata_size := mload(returndata)
|
160
|
+
revert(add(32, returndata), returndata_size)
|
161
|
+
}
|
162
|
+
} else {
|
163
|
+
revert BridgeCallFailed();
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
function calculateItemHash(
|
169
|
+
address l2Sender,
|
170
|
+
address to,
|
171
|
+
uint256 l2Block,
|
172
|
+
uint256 l1Block,
|
173
|
+
uint256 l2Timestamp,
|
174
|
+
uint256 value,
|
175
|
+
bytes calldata data
|
176
|
+
) public pure returns (bytes32) {
|
177
|
+
return
|
178
|
+
keccak256(abi.encodePacked(l2Sender, to, l2Block, l1Block, l2Timestamp, value, data));
|
179
|
+
}
|
180
|
+
|
181
|
+
function calculateMerkleRoot(
|
182
|
+
bytes32[] memory proof,
|
183
|
+
uint256 path,
|
184
|
+
bytes32 item
|
185
|
+
) public pure returns (bytes32) {
|
186
|
+
return MerkleLib.calculateRoot(proof, path, keccak256(abi.encodePacked(item)));
|
187
|
+
}
|
188
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.4;
|
6
|
+
|
7
|
+
contract RollupMock {
|
8
|
+
event WithdrawTriggered();
|
9
|
+
event ZombieTriggered();
|
10
|
+
|
11
|
+
function withdrawStakerFunds() external returns (uint256) {
|
12
|
+
emit WithdrawTriggered();
|
13
|
+
return 0;
|
14
|
+
}
|
15
|
+
|
16
|
+
function removeOldZombies(
|
17
|
+
uint256 /* startIndex */
|
18
|
+
) external {
|
19
|
+
emit ZombieTriggered();
|
20
|
+
}
|
21
|
+
}
|
package/src/state/PcStack.sol
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
-
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
-
// SPDX-License-Identifier: BUSL-1.1
|
4
|
-
|
5
|
-
pragma solidity ^0.8.0;
|
6
|
-
|
7
|
-
import "./PcArray.sol";
|
8
|
-
|
9
|
-
struct PcStack {
|
10
|
-
PcArray proved;
|
11
|
-
bytes32 remainingHash;
|
12
|
-
}
|
13
|
-
|
14
|
-
library PcStackLib {
|
15
|
-
using PcArrayLib for PcArray;
|
16
|
-
|
17
|
-
function hash(PcStack memory stack) internal pure returns (bytes32 h) {
|
18
|
-
h = stack.remainingHash;
|
19
|
-
uint256 len = stack.proved.length();
|
20
|
-
for (uint256 i = 0; i < len; i++) {
|
21
|
-
h = keccak256(abi.encodePacked("Program counter stack:", stack.proved.get(i), h));
|
22
|
-
}
|
23
|
-
}
|
24
|
-
|
25
|
-
function pop(PcStack memory stack) internal pure returns (uint32) {
|
26
|
-
return stack.proved.pop();
|
27
|
-
}
|
28
|
-
|
29
|
-
function push(PcStack memory stack, uint32 val) internal pure {
|
30
|
-
return stack.proved.push(val);
|
31
|
-
}
|
32
|
-
}
|