Skip to content

Commit

Permalink
Merge branch 'custom-fee-rollup' into fee-token-pricers
Browse files Browse the repository at this point in the history
  • Loading branch information
yahgwai committed Dec 20, 2024
2 parents b7a86ac + b805e8c commit 0858206
Show file tree
Hide file tree
Showing 46 changed files with 779 additions and 181 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Additional Use Grant: You may use the Licensed Work in a production environment
validating the correctness of the posted chain state, or to deploy
and operate (x) a blockchain that settles to a Covered Arbitrum Chain
or (y) a blockchain in accordance with, and subject to, the [Arbitrum
Expansion Program Term of Use](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf). For purposes of this
Expansion Program Term of Use](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf). For purposes of this
Additional Use Grant, the "Covered Arbitrum Chains" are
(a) Arbitrum One (chainid:42161), Arbitrum Nova (chainid:42170),
Arbitrum Rinkeby testnet/Rinkarby (chainid:421611),Arbitrum Nitro
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ It includes the rollup and fraud proof smart contracts, as well as interfaces fo

For more information see https://developer.arbitrum.io/intro

For the deployed addresses of these contracts for Arbitrum chains see https://developer.arbitrum.io/useful-addresses
For the deployed addresses of these contracts for Arbitrum chains see [https://docs.arbitrum.io/for-devs/dev-tools-and-resources/chain-info#core-contracts](https://docs.arbitrum.io/for-devs/dev-tools-and-resources/chain-info#core-contracts)

For the token bridge contracts see https://github.com/OffchainLabs/token-bridge-contracts
For the token bridge contracts see [https://github.com/OffchainLabs/token-bridge-contracts](https://github.com/OffchainLabs/token-bridge-contracts)

Compile these contracts locally by running

Expand All @@ -24,7 +24,7 @@ Nitro is currently licensed under a [Business Source License](./LICENSE.md), sim

The Additional Use Grant also permits the deployment of the Nitro software, in a permissionless fashion and without cost, as a new blockchain provided that the chain settles to either Arbitrum One or Arbitrum Nova.

For those that prefer to deploy the Nitro software either directly on Ethereum (i.e. an L2) or have it settle to another Layer-2 on top of Ethereum, the [Arbitrum Expansion Program (the "AEP")](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf) was recently established. The AEP allows for the permissionless deployment in the aforementioned fashion provided that 10% of net revenue is contributed back to the Arbitrum community in accordance with the requirements of the AEP.
For those that prefer to deploy the Nitro software either directly on Ethereum (i.e. an L2) or have it settle to another Layer-2 on top of Ethereum, the [Arbitrum Expansion Program (the "AEP")](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf) was recently established. The AEP allows for the permissionless deployment in the aforementioned fashion provided that 10% of net revenue is contributed back to the Arbitrum community in accordance with the requirements of the AEP.

## Contact

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@arbitrum/nitro-contracts",
"version": "3.0.0-alpha.2",
"version": "3.0.0-beta.0",
"description": "Layer 2 precompiles and rollup for Arbitrum Nitro",
"author": "Offchain Labs, Inc.",
"license": "BUSL-1.1",
Expand Down
19 changes: 16 additions & 3 deletions scripts/boldUpgradeCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,17 @@ export const getConfig = async (
if (!config) {
throw new Error('config not found')
}
if (process.env.ROLLUP_ADDRESS) {
console.log('Using ROLLUP_ADDRESS from env:', process.env.ROLLUP_ADDRESS)
config.contracts.rollup = process.env.ROLLUP_ADDRESS
// in testnode mode we allow some config to be overridden from env for easier testing
if (process.env.TESTNODE_MODE) {
console.log('In testnode mode')
if (process.env.ROLLUP_ADDRESS) {
console.log('Using ROLLUP_ADDRESS from env:', process.env.ROLLUP_ADDRESS)
config.contracts.rollup = process.env.ROLLUP_ADDRESS
}
if (process.env.STAKE_TOKEN) {
console.log('Using STAKE_TOKEN from env:', process.env.STAKE_TOKEN)
config.settings.stakeToken = process.env.STAKE_TOKEN
}
}
await validateConfig(config, l1Rpc)
return config
Expand Down Expand Up @@ -68,6 +76,8 @@ export interface Config {
stakeAmt: BigNumber
miniStakeAmounts: BigNumber[]
chainId: number
minimumAssertionPeriod: number
validatorAfkBlocks: number
disableValidatorWhitelist: boolean
maxDataSize: number
blockLeafSize: number
Expand Down Expand Up @@ -138,6 +148,9 @@ export const validateConfig = async (
if (config.settings.stakeToken.length === 0) {
throw new Error('stakeToken address is empty')
}
if ((await l1Rpc.getCode(config.settings.stakeToken)).length <= 2) {
throw new Error('stakeToken address is not a contract')
}
if (config.settings.chainId === 0) {
throw new Error('chainId is 0')
}
Expand Down
2 changes: 2 additions & 0 deletions scripts/config.ts.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export const config = {
owner: '0x1234123412341234123412341234123412341234',
loserStakeEscrow: ethers.constants.AddressZero,
chainId: ethers.BigNumber.from('13331370'),
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
chainConfig:
'{"chainId":13331370,"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":"0x1234123412341234123412341234123412341234","GenesisBlockNum":0}}',
genesisBlockNum: ethers.BigNumber.from('0'),
Expand Down
2 changes: 2 additions & 0 deletions scripts/files/configs/arb1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export const arb1: Config = {
stakeAmt: parseEther('3600'),
miniStakeAmounts: [parseEther('0'), parseEther('555'), parseEther('79')],
chainId: 42161,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: true,
blockLeafSize: 2 ** 26,
bigStepLeafSize: 2 ** 19,
Expand Down
6 changes: 4 additions & 2 deletions scripts/files/configs/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const local: Config = {
parseEther('1'),
],
chainId: 412346,
minimumAssertionPeriod: 0,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: true,
blockLeafSize: 1048576,
bigStepLeafSize: 512,
Expand All @@ -43,8 +45,8 @@ export const local: Config = {
maxDataSize: 117964,
isDelayBufferable: true,
bufferConfig: {
max: 14400,
threshold: 300,
max: 2 ** 32, // effectively disableing and will be enabled later
threshold: 2 ** 32, // effectively disableing and will be enabled later
replenishRateInBasis: 500,
},
},
Expand Down
2 changes: 2 additions & 0 deletions scripts/files/configs/nova.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const nova: Config = {
stakeAmt: parseEther('1'),
miniStakeAmounts: [parseEther('0'), parseEther('1'), parseEther('1')],
chainId: 42170,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: false,
blockLeafSize: 2 ** 26, // leaf sizes same as arb1
bigStepLeafSize: 2 ** 19,
Expand Down
6 changes: 4 additions & 2 deletions scripts/files/configs/sepolia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export const sepolia: Config = {
stakeAmt: parseEther('36'), // 1/100th of arb1, same for mini stakes
miniStakeAmounts: [parseEther('0'), parseEther('5.5'), parseEther('0.79')],
chainId: 421614,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: false,
blockLeafSize: 2 ** 26, // leaf sizes same as arb1
bigStepLeafSize: 2 ** 19,
Expand All @@ -36,8 +38,8 @@ export const sepolia: Config = {
maxDataSize: 117964,
isDelayBufferable: true,
bufferConfig: {
max: hoursToBlocks(24 * 365), // 365 days, effectively disableing and will be enabled later
threshold: hoursToBlocks(24 * 365), // 365 days, effectively disableing and will be enabled later
max: 2 ** 32, // effectively disableing and will be enabled later
threshold: 2 ** 32, // effectively disableing and will be enabled later
replenishRateInBasis: 500, // 5% replenishment rate
},
},
Expand Down
32 changes: 15 additions & 17 deletions scripts/files/sepoliaDeployedContracts.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
{
"bridge": "0x723B45e3233652F64a399C260380AFC4a33F3f9D",
"seqInbox": "0x20B2b541f3382BFB11310Bd53D1C76b015E54775",
"rei": "0xB14D2319BABDd03577f3697340323219cCdA2641",
"outbox": "0x5594a90b3d150f06a16dB5866f47B7F528D35D74",
"inbox": "0x66e62BdeBCCEa538bA9938225a885a5c4D59C117",
"oldRollupUser": "0xcBfA2F189DCA8526Ec0266dB79d6F789b1b32e9e",
"newRollupUser": "0xEcfed86caB17269295E76d1906539bbAbbb3F407",
"newRollupAdmin": "0x61aE32e7dD698c719dDa77688f40F20c4dBdf598",
"challengeManager": "0xF69B6B6Db566df9611ddc2A1C3205C6E4E8c1Ba0",
"prover0": "0x6Dd038e1C80CAa19959D7e3CC302762a1788cc04",
"proverMem": "0x545e0dAbE2dA95515563cecED861420Ec60A0244",
"proverMath": "0x71f1904d9018087722fbF8EBB03be149A59405E2",
"proverHostIo": "0x409CcfCeDF546DE7B855191cC5B7f6EF318d406C",
"osp": "0x32362a2884232d05df32feDeb18a9aBb89A8cf7b",
"boldAction": "0xD45D3C6a11a90a6c91c45E8086076a86ACd5d14c",
"rollupReader": "0x59e367A39b8dBF4Db1b3e6FfC8e8294c5029bCaB",
"preImageHashLookup": "0x1b40DFd553145153c6B93B5B17D505d8156baBB6"
"bridge": "0xED26e46f38957763f83f2C45f6Fb6702cfEBc7D8",
"seqInbox": "0xBBb2EF6dD70759F6c335c116895c6749ec7427da",
"rei": "0x53554562D5B4B02aeFaE6489481D6fc3C3Fa995B",
"outbox": "0xFeD2027E956fa0a1F367c03a20555839441E224f",
"inbox": "0x4B31D35CE007C9744E71dB8fc649629f3B7C619E",
"newRollupUser": "0xDC2f809Bba33Cbb96a5EA8e9EE2DD4cB104E0BA5",
"newRollupAdmin": "0x3b7aEa898C7F51551DAAff4dae8aB0F553f2AEF8",
"challengeManager": "0xC14422cCa7D6462CCBeA5FEEc08ffbae66713fFE",
"prover0": "0x3Fe73F959C44e04d660dBFBbeffd51FD2c091377",
"proverMem": "0x6268Fc8dB1b5083b405b2C51808Df3619783ec2d",
"proverMath": "0x42f58c90583eC3fA0E0b724dEDF755AE1068e8Fa",
"proverHostIo": "0xdB2c541e20Bd1830c8a050341Fca0Af51489C165",
"osp": "0xB9cf664A1beD8F74f4B893a18c86eCe876CdAE80",
"boldAction": "0xf8199Ca3702C09c78B957D4D820311125753C6d2",
"preImageHashLookup": "0x421f2cE0f49095EB8d50aCB903799845C7315fb9"
}
2 changes: 2 additions & 0 deletions scripts/rollupCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ async function _getDevRollupConfig(
loserStakeEscrow: ethers.constants.AddressZero,
chainId: JSON.parse(chainConfig)['chainId'],
chainConfig: chainConfig,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
genesisAssertionState: {}, // AssertionState
genesisInboxCount: 0,
miniStakeValues: [
Expand Down
2 changes: 1 addition & 1 deletion slither.db.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/bridge/AbsBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ abstract contract AbsBridge is Initializable, DelegateCallAware, IBridge {
}
sequencerReportedSubMessageCount = newMessageCount;
seqMessageIndex = sequencerInboxAccs.length;
if (sequencerInboxAccs.length > 0) {
beforeAcc = sequencerInboxAccs[sequencerInboxAccs.length - 1];
if (seqMessageIndex > 0) {
beforeAcc = sequencerInboxAccs[seqMessageIndex - 1];
}
if (afterDelayedMessagesRead > 0) {
delayedAcc = delayedInboxAccs[afterDelayedMessagesRead - 1];
Expand Down
8 changes: 6 additions & 2 deletions src/bridge/ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ contract ERC20Bridge is AbsBridge, IERC20Bridge {
uint256 amount
) internal override {
// fetch native token from Inbox
IERC20(nativeToken).safeTransferFrom(msg.sender, address(this), amount);
if (amount > 0) {
IERC20(nativeToken).safeTransferFrom(msg.sender, address(this), amount);
}
}

function _executeLowLevelCall(
Expand All @@ -95,7 +97,9 @@ contract ERC20Bridge is AbsBridge, IERC20Bridge {
}

// first release native token
IERC20(_nativeToken).safeTransfer(to, value);
if (value > 0) {
IERC20(_nativeToken).safeTransfer(to, value);
}
success = true;

// if there's data do additional contract call. Make sure that call is not used to
Expand Down
28 changes: 9 additions & 19 deletions src/rollup/BOLDUpgradeAction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ contract BOLDUpgradeAction {
address public immutable STAKE_TOKEN;
uint256 public immutable STAKE_AMOUNT;
uint256 public immutable CHAIN_ID;
uint256 public immutable MINIMUM_ASSERTION_PERIOD;
uint64 public immutable VALIDATOR_AFK_BLOCKS;

bool public immutable DISABLE_VALIDATOR_WHITELIST;
uint64 public immutable CHALLENGE_GRACE_PERIOD_BLOCKS;
address public immutable MINI_STAKE_AMOUNTS_STORAGE;
Expand Down Expand Up @@ -223,6 +226,8 @@ contract BOLDUpgradeAction {
uint256 stakeAmt;
uint256[] miniStakeAmounts;
uint256 chainId;
uint256 minimumAssertionPeriod;
uint64 validatorAfkBlocks;
bool disableValidatorWhitelist;
uint256 blockLeafSize;
uint256 bigStepLeafSize;
Expand Down Expand Up @@ -296,6 +301,8 @@ contract BOLDUpgradeAction {
IMPL_CHALLENGE_MANAGER = implementations.challengeManager;

CHAIN_ID = settings.chainId;
MINIMUM_ASSERTION_PERIOD = settings.minimumAssertionPeriod;
VALIDATOR_AFK_BLOCKS = settings.validatorAfkBlocks;
CONFIRM_PERIOD_BLOCKS = settings.confirmPeriodBlocks;
CHALLENGE_PERIOD_BLOCKS = settings.challengePeriodBlocks;
STAKE_TOKEN = settings.stakeToken;
Expand Down Expand Up @@ -373,6 +380,8 @@ contract BOLDUpgradeAction {
loserStakeEscrow: EXCESS_STAKE_RECEIVER, // additional funds get sent to the l1 timelock
chainId: CHAIN_ID,
chainConfig: "", // we can use an empty chain config it wont be used in the rollup initialization because we check if the rei is already connected there
minimumAssertionPeriod: MINIMUM_ASSERTION_PERIOD,
validatorAfkBlocks: VALIDATOR_AFK_BLOCKS,
miniStakeValues: ConstantArrayStorage(MINI_STAKE_AMOUNTS_STORAGE).array(),
sequencerInboxMaxTimeVariation: maxTimeVariation,
layerZeroBlockEdgeHeight: BLOCK_LEAF_SIZE,
Expand Down Expand Up @@ -433,17 +442,6 @@ contract BOLDUpgradeAction {
PROXY_ADMIN_SEQUENCER_INBOX.upgrade(sequencerInbox, IMPL_SEQUENCER_INBOX);
}

// verify
require(
PROXY_ADMIN_SEQUENCER_INBOX.getProxyImplementation(sequencerInbox)
== IMPL_SEQUENCER_INBOX,
"DelayBuffer: new seq inbox implementation not set"
);
require(
ISequencerInbox(SEQ_INBOX).isDelayBufferable() == IS_DELAY_BUFFERABLE,
"DelayBuffer: isDelayBufferable not set"
);

(uint256 delayBlocks, uint256 futureBlocks, uint256 delaySeconds, uint256 futureSeconds) =
ISequencerInbox(SEQ_INBOX).maxTimeVariation();

Expand All @@ -465,14 +463,6 @@ contract BOLDUpgradeAction {
})
);

// verify
(uint256 _delayBlocks, uint256 _futureBlocks, uint256 _delaySeconds, uint256 _futureSeconds)
= ISequencerInbox(SEQ_INBOX).maxTimeVariation();
require(_delayBlocks == delayBlocks, "DelayBuffer: delayBlocks");
require(_delaySeconds == delaySeconds, "DelayBuffer: delaySeconds");
require(_futureBlocks == futureBlocks, "DelayBuffer: futureBlocks");
require(_futureSeconds == futureSeconds, "DelayBuffer: futureSeconds");

ISequencerInbox(SEQ_INBOX).updateRollupAddress();
}

Expand Down
28 changes: 23 additions & 5 deletions src/rollup/BridgeCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,22 @@ contract BridgeCreator is Ownable {
}

function _createBridge(
bytes32 create2Salt,
address adminProxy,
BridgeTemplates memory templates,
bool isDelayBufferable
) internal returns (BridgeContracts memory) {
BridgeContracts memory frame;
frame.bridge = IBridge(
address(new TransparentUpgradeableProxy(address(templates.bridge), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.bridge), adminProxy, ""
)
)
);
frame.sequencerInbox = ISequencerInbox(
address(
new TransparentUpgradeableProxy(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(
isDelayBufferable
? templates.delayBufferableSequencerInbox
Expand All @@ -87,15 +92,25 @@ contract BridgeCreator is Ownable {
)
);
frame.inbox = IInboxBase(
address(new TransparentUpgradeableProxy(address(templates.inbox), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.inbox), adminProxy, ""
)
)
);
frame.rollupEventInbox = IRollupEventInbox(
address(
new TransparentUpgradeableProxy(address(templates.rollupEventInbox), adminProxy, "")
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.rollupEventInbox), adminProxy, ""
)
)
);
frame.outbox = IOutbox(
address(new TransparentUpgradeableProxy(address(templates.outbox), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.outbox), adminProxy, ""
)
)
);
return frame;
}
Expand All @@ -108,11 +123,14 @@ contract BridgeCreator is Ownable {
BufferConfig calldata bufferConfig,
IFeeTokenPricer feeTokenPricer
) external returns (BridgeContracts memory) {
// use create2 salt to ensure deterministic addresses
bytes32 create2Salt = keccak256(abi.encode(msg.data, msg.sender));
// create delay bufferable sequencer inbox if threshold is non-zero
bool isDelayBufferable = bufferConfig.threshold != 0;

// create ETH-based bridge if address zero is provided for native token, otherwise create ERC20-based bridge
BridgeContracts memory frame = _createBridge(
create2Salt,
adminProxy,
nativeToken == address(0) ? ethBasedTemplates : erc20BasedTemplates,
isDelayBufferable
Expand Down
2 changes: 2 additions & 0 deletions src/rollup/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ struct Config {
address loserStakeEscrow;
uint256 chainId;
string chainConfig;
uint256 minimumAssertionPeriod;
uint64 validatorAfkBlocks;
uint256[] miniStakeValues;
ISequencerInbox.MaxTimeVariation sequencerInboxMaxTimeVariation;
uint256 layerZeroBlockEdgeHeight;
Expand Down
8 changes: 4 additions & 4 deletions src/rollup/RollupAdminLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ contract RollupAdminLogic is RollupCore, IRollupAdmin, DoubleLogicUUPSUpgradeabl
chainId = config.chainId;
baseStake = config.baseStake;
wasmModuleRoot = config.wasmModuleRoot;
// A little over 15 minutes
minimumAssertionPeriod = 75;
// ValidatorAfkBlocks is defaulted to 28 days assuming a 12 seconds block time.
// minimumAssertionPeriod was defaulted to 75 which is a little over 15 minutes
minimumAssertionPeriod = config.minimumAssertionPeriod;
// ValidatorAfkBlocks was defaulted to 201600 which is 28 days assuming a 12 seconds block time.
// Since it can take 14 days under normal circumstances to confirm an assertion, this means
// the validators will have been inactive for a further 14 days before the whitelist is removed.
validatorAfkBlocks = 201600;
validatorAfkBlocks = config.validatorAfkBlocks;
challengeGracePeriodBlocks = config.challengeGracePeriodBlocks;

// loser stake is now sent directly to loserStakeEscrow, it must not
Expand Down
2 changes: 2 additions & 0 deletions test/Rollup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ contract RollupTest is Test {
baseStake: BASE_STAKE,
chainId: 0,
chainConfig: "{}",
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
confirmPeriodBlocks: uint64(CONFIRM_PERIOD_BLOCKS),
owner: owner,
sequencerInboxMaxTimeVariation: ISequencerInbox.MaxTimeVariation({
Expand Down
Loading

0 comments on commit 0858206

Please sign in to comment.