Skip to content

Commit 14d2cd4

Browse files
committed
Merge remote-tracking branch 'origin/develop' into batch-poster-manager
2 parents 7364e6a + b4c739f commit 14d2cd4

10 files changed

+325
-53
lines changed

deploy/SequencerInboxStubCreator.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ module.exports = async hre => {
1717
}
1818
await deploy('SequencerInboxStub', {
1919
from: deployer,
20-
args: [bridge.address, deployer, maxTime, 117964, reader4844.address],
20+
args: [
21+
bridge.address,
22+
deployer,
23+
maxTime,
24+
117964,
25+
reader4844.address,
26+
false,
27+
],
2128
})
2229
}
2330

scripts/deployment.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ async function deployAllContracts(
8181
const ethBridge = await deployContract('Bridge', signer, [])
8282
const ethSequencerInbox = await deployContract('SequencerInbox', signer, [
8383
maxDataSize,
84+
false,
8485
])
8586
const ethInbox = await deployContract('Inbox', signer, [maxDataSize])
8687
const ethRollupEventInbox = await deployContract(
@@ -91,7 +92,10 @@ async function deployAllContracts(
9192
const ethOutbox = await deployContract('Outbox', signer, [])
9293

9394
const erc20Bridge = await deployContract('ERC20Bridge', signer, [])
94-
const erc20SequencerInbox = ethSequencerInbox
95+
const erc20SequencerInbox = await deployContract('SequencerInbox', signer, [
96+
maxDataSize,
97+
true,
98+
])
9599
const erc20Inbox = await deployContract('ERC20Inbox', signer, [maxDataSize])
96100
const erc20RollupEventInbox = await deployContract(
97101
'ERC20RollupEventInbox',

src/bridge/SequencerInbox.sol

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
NoSuchKeyset,
2424
NotForked,
2525
NotBatchPosterManager,
26+
RollupNotChanged,
2627
DataBlobsNotSupported,
2728
InitParamZero,
2829
MissingDataHashes,
@@ -31,6 +32,7 @@ import {
3132
RollupNotChanged,
3233
EmptyBatchData,
3334
InvalidHeaderFlag,
35+
NativeTokenMismatch,
3436
Deprecated
3537
} from "../libraries/Error.sol";
3638
import "./IBridge.sol";
@@ -47,6 +49,7 @@ import "../libraries/DelegateCallAware.sol";
4749
import {IGasRefunder} from "../libraries/IGasRefunder.sol";
4850
import {GasRefundEnabled} from "../libraries/GasRefundEnabled.sol";
4951
import "../libraries/ArbitrumChecker.sol";
52+
import {IERC20Bridge} from "./IERC20Bridge.sol";
5053

5154
/**
5255
* @title Accepts batches from the sequencer and adds them to the rollup inbox.
@@ -122,15 +125,22 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
122125
uint256 internal immutable deployTimeChainId = block.chainid;
123126
// If the chain this SequencerInbox is deployed on is an Arbitrum chain.
124127
bool internal immutable hostChainIsArbitrum = ArbitrumChecker.runningOnArbitrum();
125-
126-
constructor(uint256 _maxDataSize, IReader4844 reader4844_) {
128+
// True if the chain this SequencerInbox is deployed on uses custom fee token
129+
bool public immutable isUsingFeeToken;
130+
131+
constructor(
132+
uint256 _maxDataSize,
133+
IReader4844 reader4844_,
134+
bool _isUsingFeeToken
135+
) {
127136
maxDataSize = _maxDataSize;
128137
if (hostChainIsArbitrum) {
129138
if (reader4844_ != IReader4844(address(0))) revert DataBlobsNotSupported();
130139
} else {
131140
if (reader4844_ == IReader4844(address(0))) revert InitParamZero("Reader4844");
132141
}
133142
reader4844 = reader4844_;
143+
isUsingFeeToken = _isUsingFeeToken;
134144
}
135145

136146
function _chainIdChanged() internal view returns (bool) {
@@ -175,6 +185,19 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
175185
) external onlyDelegated {
176186
if (bridge != IBridge(address(0))) revert AlreadyInit();
177187
if (bridge_ == IBridge(address(0))) revert HadZeroInit();
188+
189+
// Make sure logic contract was created by proper value for 'isUsingFeeToken'.
190+
// Bridge in ETH based chains doesn't implement nativeToken(). In future it might implement it and return address(0)
191+
bool actualIsUsingFeeToken = false;
192+
try IERC20Bridge(address(bridge_)).nativeToken() returns (address feeToken) {
193+
if (feeToken != address(0)) {
194+
actualIsUsingFeeToken = true;
195+
}
196+
} catch {}
197+
if (isUsingFeeToken != actualIsUsingFeeToken) {
198+
revert NativeTokenMismatch();
199+
}
200+
178201
bridge = bridge_;
179202
rollup = bridge_.rollup();
180203
delayBlocks = maxTimeVariation_.delayBlocks;
@@ -444,7 +467,7 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
444467
// same as using calldata, we only submit spending report if the caller is the origin of the tx
445468
// such that one cannot "double-claim" batch posting refund in the same tx
446469
// solhint-disable-next-line avoid-tx-origin
447-
if (msg.sender == tx.origin) {
470+
if (msg.sender == tx.origin && !isUsingFeeToken) {
448471
submitBatchSpendingReport(dataHash, seqMessageIndex, block.basefee, blobGas);
449472
}
450473
}
@@ -682,7 +705,8 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
682705

683706
totalDelayedMessagesRead = afterDelayedMessagesRead;
684707

685-
if (calldataLengthPosted > 0) {
708+
if (calldataLengthPosted > 0 && !isUsingFeeToken) {
709+
// only report batch poster spendings if chain is using ETH as native currency
686710
submitBatchSpendingReport(dataHash, seqMessageIndex, block.basefee, 0);
687711
}
688712
}

src/libraries/Error.sol

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,5 +200,8 @@ error EmptyBatchData();
200200
/// @dev Unsupported header flag was provided
201201
error InvalidHeaderFlag(bytes1);
202202

203+
/// @dev SequencerInbox and Bridge are not in the same feeToken/ETH mode
204+
error NativeTokenMismatch();
205+
203206
/// @dev Thrown when a deprecated function is called
204207
error Deprecated();

src/mocks/SequencerInboxStub.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ contract SequencerInboxStub is SequencerInbox {
1414
address sequencer_,
1515
ISequencerInbox.MaxTimeVariation memory maxTimeVariation_,
1616
uint256 maxDataSize_,
17-
IReader4844 reader4844_
18-
) SequencerInbox(maxDataSize_, reader4844_) {
17+
IReader4844 reader4844_,
18+
bool isUsingFeeToken_
19+
) SequencerInbox(maxDataSize_, reader4844_, isUsingFeeToken_) {
1920
bridge = bridge_;
2021
rollup = IOwnable(msg.sender);
2122
delayBlocks = maxTimeVariation_.delayBlocks;

test/contract/arbRollup.spec.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ const setup = async () => {
193193
)) as SequencerInbox__factory
194194
const ethSequencerInbox = await ethSequencerInboxFac.deploy(
195195
117964,
196-
dummy4844Reader
196+
dummy4844Reader,
197+
false
197198
)
198199

199200
const ethInboxFac = (await ethers.getContractFactory(
@@ -216,7 +217,14 @@ const setup = async () => {
216217
)) as ERC20Bridge__factory
217218
const erc20Bridge = await erc20BridgeFac.deploy()
218219

219-
const erc20SequencerInbox = ethSequencerInbox
220+
const erc20SequencerInboxFac = (await ethers.getContractFactory(
221+
'SequencerInbox'
222+
)) as SequencerInbox__factory
223+
const erc20SequencerInbox = await erc20SequencerInboxFac.deploy(
224+
117964,
225+
dummy4844Reader,
226+
true
227+
)
220228

221229
const erc20InboxFac = (await ethers.getContractFactory(
222230
'ERC20Inbox'

test/contract/sequencerInboxForceInclude.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ describe('SequencerInboxForceInclude', async () => {
238238
)) as SequencerInbox__factory
239239
const seqInboxTemplate = await sequencerInboxFac.deploy(
240240
117964,
241-
reader4844.address
241+
reader4844.address,
242+
false
242243
)
243244
const inboxFac = (await ethers.getContractFactory(
244245
'Inbox'

test/foundry/BridgeCreator.t.sol

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ contract BridgeCreatorTest is Test {
2020
bridge: new Bridge(),
2121
sequencerInbox: new SequencerInbox(
2222
MAX_DATA_SIZE,
23-
dummyReader4844
23+
dummyReader4844,
24+
false
2425
),
2526
inbox: new Inbox(MAX_DATA_SIZE),
2627
rollupEventInbox: new RollupEventInbox(),
@@ -29,7 +30,11 @@ contract BridgeCreatorTest is Test {
2930
BridgeCreator.BridgeContracts erc20BasedTemplates =
3031
BridgeCreator.BridgeContracts({
3132
bridge: new ERC20Bridge(),
32-
sequencerInbox: ethBasedTemplates.sequencerInbox,
33+
sequencerInbox: new SequencerInbox(
34+
MAX_DATA_SIZE,
35+
dummyReader4844,
36+
true
37+
),
3338
inbox: new ERC20Inbox(MAX_DATA_SIZE),
3439
rollupEventInbox: new ERC20RollupEventInbox(),
3540
outbox: new ERC20Outbox()
@@ -40,7 +45,7 @@ contract BridgeCreatorTest is Test {
4045
creator = new BridgeCreator(ethBasedTemplates, erc20BasedTemplates);
4146
}
4247

43-
function getEthBasedTemplates() internal returns (BridgeCreator.BridgeContracts memory) {
48+
function getEthBasedTemplates() internal view returns (BridgeCreator.BridgeContracts memory) {
4449
BridgeCreator.BridgeContracts memory templates;
4550
(
4651
templates.bridge,
@@ -52,7 +57,7 @@ contract BridgeCreatorTest is Test {
5257
return templates;
5358
}
5459

55-
function getErc20BasedTemplates() internal returns (BridgeCreator.BridgeContracts memory) {
60+
function getErc20BasedTemplates() internal view returns (BridgeCreator.BridgeContracts memory) {
5661
BridgeCreator.BridgeContracts memory templates;
5762
(
5863
templates.bridge,

test/foundry/RollupCreator.t.sol

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,20 @@ contract RollupCreatorTest is Test {
3737
bridge: new Bridge(),
3838
sequencerInbox: new SequencerInbox(
3939
MAX_DATA_SIZE,
40-
dummyReader4844
40+
dummyReader4844,
41+
false
4142
),
4243
inbox: new Inbox(MAX_DATA_SIZE),
4344
rollupEventInbox: new RollupEventInbox(),
4445
outbox: new Outbox()
4546
});
4647
BridgeCreator.BridgeContracts public erc20BasedTemplates = BridgeCreator.BridgeContracts({
4748
bridge: new ERC20Bridge(),
48-
sequencerInbox: ethBasedTemplates.sequencerInbox,
49+
sequencerInbox: new SequencerInbox(
50+
MAX_DATA_SIZE,
51+
dummyReader4844,
52+
true
53+
),
4954
inbox: new ERC20Inbox(MAX_DATA_SIZE),
5055
rollupEventInbox: new ERC20RollupEventInbox(),
5156
outbox: new ERC20Outbox()

0 commit comments

Comments
 (0)