Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
ae40939
Add CustomDA proof validation interface and reference implementation
Tristan-Wilson Jun 18, 2025
f20cebe
Merge remote-tracking branch 'origin/develop' into customda-bold
gzeoneth Jun 18, 2025
ea132b7
format: yarn format
gzeoneth Jun 18, 2025
aad9ebc
fix: 0x01
gzeoneth Jun 18, 2025
c63dc45
wip: use create2 for factory deployment
godzillaba Jun 24, 2025
0040293
remove key from config
godzillaba Jun 24, 2025
40b97dd
fmt
godzillaba Jun 24, 2025
22ad2fa
fix signatures
godzillaba Jun 24, 2025
9b38201
Merge branch 'develop' into deterministic-factory-deployments
godzillaba Jun 24, 2025
ac0ba75
Merge remote-tracking branch 'origin/develop' into customda-bold
gzeoneth Jun 25, 2025
2854f5d
refactor: make OneStepProverHostIo validator immutable
gzeoneth Jun 25, 2025
a49b1a2
test: storage and 4bytes
gzeoneth Jun 25, 2025
54f5ac3
test: simple CustomDAProof test
gzeoneth Jun 25, 2025
08fa02b
chore: restore file
gzeoneth Jun 25, 2025
094b86f
fix: triage slither
gzeoneth Jun 25, 2025
17be158
inline up exec deployment
godzillaba Jun 25, 2025
5865eb7
Merge branch 'develop' into customda-bold
gzeoneth Jun 25, 2025
631b941
chore: move file to foundry test folder
gzeoneth Jun 26, 2025
8aed0c3
salt length check
godzillaba Jun 30, 2025
7c0fd72
update tests
godzillaba Jun 30, 2025
4412691
Merge branch 'develop' into deterministic-factory-deployments
godzillaba Jun 30, 2025
1a12320
fmt
godzillaba Jun 30, 2025
64a519a
Merge branch 'deterministic-factory-deployments' of https://github.co…
godzillaba Jun 30, 2025
c4887b3
remove SetTemplatesArgs struct
godzillaba Jul 1, 2025
f4ba76f
remove ownership from bridge creator
godzillaba Jul 1, 2025
5953155
add CREATE2_FACTORY env and deployment instructions
godzillaba Jul 1, 2025
9429824
fix signatures
godzillaba Jul 1, 2025
f760491
factory owner as deployAllContracts arg
godzillaba Jul 1, 2025
bd06fb1
set deployer as owner in local deployment
godzillaba Jul 1, 2025
a2d4228
chore: disable metahash and align hardhat foundry (#363)
godzillaba Jul 3, 2025
1b86d38
fix: deploy create2 factory for local deployment
gzeoneth Jul 3, 2025
89baf3a
fix: wait for funding
gzeoneth Jul 3, 2025
d74b01b
ci: use geth-allow-pre155
gzeoneth Jul 3, 2025
9373a97
fix: _uint256ToAddress helper
gzeoneth Jul 3, 2025
dbeef90
test: fix ReferenceDAProofValidatorTest
gzeoneth Jul 7, 2025
442e95b
Merge branch 'deterministic-factory-deployments' into customda-bold
gzeoneth Jul 7, 2025
9323db7
fix: 4bytes and storage
gzeoneth Jul 7, 2025
e508d7f
wip: make rollup creator support customda feature (#361)
gzeoneth Jul 7, 2025
98fd84a
Check certKeccak against proven hash in memory
Tristan-Wilson Jul 11, 2025
221ddc5
Move cert into standardized part of OSP validation
Tristan-Wilson Jul 11, 2025
656325c
Simplify CustomDA proof format and fix stack depth error
Tristan-Wilson Jul 11, 2025
1e23170
format: yarn format
gzeoneth Jul 11, 2025
9afeb45
test: fix
gzeoneth Jul 11, 2025
b36526e
test: refactor
gzeoneth Jul 11, 2025
7d0ab0b
test: add more coverage
gzeoneth Jul 11, 2025
e18761e
Add ValidatePreimage inst for CustomDA cert val OSP
Tristan-Wilson Jul 15, 2025
9204f87
feat: add trusted signer validation to ReferenceDAProofValidator
Tristan-Wilson Jul 21, 2025
555e3a2
Fix hostio range
Tristan-Wilson Aug 25, 2025
7274410
Merge remote-tracking branch 'origin/develop' into customda-bold
gzeoneth Sep 9, 2025
b85e20c
chore: disable forge lint_on_build
gzeoneth Sep 9, 2025
44b2eb4
refactor: avoid assembly
gzeoneth Sep 22, 2025
1dc6253
chore: check nonzero customDAValidator
gzeoneth Sep 22, 2025
8002d8a
refactor: isValid
gzeoneth Sep 22, 2025
2ba9919
refcator: avoid more assembly
gzeoneth Sep 22, 2025
50e5127
Rename VALIDATE_PREIMAGE opcode to VALIDATE_CERTIFICATE
Tristan-Wilson Sep 30, 2025
d8474b7
Replace hardcoded proof offset values with constants
Tristan-Wilson Sep 30, 2025
cba26f2
Return up to 32 bytes from validateReadPreimage
Tristan-Wilson Sep 30, 2025
8a9a3d8
Move ReferenceDAProofValidator.sol out of contracts
Oct 6, 2025
1160b95
Fix: Read certificate size from correct offset in validateAndCheckCer…
Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy/OneStepProverHostIoCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = async hre => {

await deploy('OneStepProverHostIo', {
from: deployer,
args: [],
args: [ethers.constants.AddressZero],
})
}

Expand Down
3 changes: 3 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,7 @@ sort_imports = false
[fuzz]
runs = 1000

[lint]
lint_on_build = false

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
3 changes: 2 additions & 1 deletion scripts/config.example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {

type PartialRollupParams = Pick<
RollupCreator.RollupDeploymentParamsStruct,
'config' | 'validators' | 'batchPosterManager' | 'batchPosters'
'config' | 'validators' | 'batchPosterManager' | 'batchPosters' | 'customOsp'
>

// 90% of Geth's 128KB tx size limit, leaving ~13KB for proving
Expand Down Expand Up @@ -68,6 +68,7 @@ export const config: PartialRollupParams = {
],
batchPosterManager: '0x1234123412341234123412341234123412341234',
batchPosters: ['0x1234123412341234123412341234123412341234'],
customOsp: ethers.constants.AddressZero,
}

// These value should be defined in the env
Expand Down
8 changes: 7 additions & 1 deletion scripts/createERC20Rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ async function main() {
feeTokenPricer = ethers.constants.AddressZero
}

let customOsp = process.env.CUSTOM_OSP_ADDRESS as string
if (!customOsp) {
customOsp = ethers.constants.AddressZero
}

console.log(
'Creating new rollup with',
customFeeTokenAddress,
Expand All @@ -56,7 +61,8 @@ async function main() {
rollupCreatorAddress,
customFeeTokenAddress,
feeTokenPricer,
stakeTokenAddress
stakeTokenAddress,
customOsp
)
}

Expand Down
8 changes: 7 additions & 1 deletion scripts/createEthRollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ async function main() {
throw new Error('STAKE_TOKEN_ADDRESS not set')
}

let customOsp = process.env.CUSTOM_OSP_ADDRESS as string
if (!customOsp) {
customOsp = ethers.constants.AddressZero
}

const [signer] = await ethers.getSigners()

await createRollup(
Expand All @@ -23,7 +28,8 @@ async function main() {
rollupCreatorAddress,
feeToken,
feeTokenPricer,
stakeTokenAddress
stakeTokenAddress,
customOsp
)
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/deploymentUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ export async function deployAllContracts(
const proverHostIo = await deployContract(
'OneStepProverHostIo',
signer,
[],
[ethers.constants.AddressZero],
verify,
true
)
Expand Down
8 changes: 7 additions & 1 deletion scripts/local-deployment/deployCreatorAndCreateRollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ async function main() {
console.log('WETH deployed at', stakeToken)
}

let customOsp = process.env.CUSTOM_OSP_ADDRESS as string
if (!customOsp) {
customOsp = ethers.constants.AddressZero
}

const factoryCode = await deployerWallet.provider.getCode(
'0x4e59b44847b379578588920ca78fbf26c0b4956c'
)
Expand Down Expand Up @@ -116,7 +121,8 @@ async function main() {
contracts.rollupCreator.address,
feeToken,
feeTokenPricer,
stakeToken
stakeToken,
customOsp
)

if (!result) {
Expand Down
15 changes: 11 additions & 4 deletions scripts/rollupCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ export async function createRollup(
rollupCreatorAddress: string,
feeToken: string,
feeTokenPricer: string,
stakeToken: string
stakeToken: string,
customOsp: string
): Promise<{
rollupCreationResult: RollupCreationResult
chainInfo: ChainInfo
Expand Down Expand Up @@ -112,7 +113,8 @@ export async function createRollup(
feeToken,
feeTokenPricer,
validatorWalletCreator,
stakeToken
stakeToken,
customOsp
)
: {
config: config.config,
Expand All @@ -124,9 +126,12 @@ export async function createRollup(
batchPosters: config.batchPosters,
batchPosterManager: config.batchPosterManager,
feeTokenPricer: feeTokenPricer,
customOsp: config.customOsp,
}

const createRollupTx = await rollupCreator.createRollup(deployParams, {
const createRollupTx = await rollupCreator.functions[
'createRollup(((uint64,address,uint256,bytes32,address,address,uint256,string,uint256,uint64,uint256[],(uint256,uint256,uint256,uint256),uint256,uint256,uint256,((bytes32[2],uint64[2]),uint8,bytes32),uint256,address,uint8,uint64,(uint64,uint64,uint64)),address[],uint256,address,bool,uint256,address[],address,address,address))'
](deployParams, {
value: feeCost,
})
const createRollupReceipt = await createRollupTx.wait()
Expand Down Expand Up @@ -235,7 +240,8 @@ async function _getDevRollupConfig(
feeToken: string,
feeTokenPricer: string,
validatorWalletCreator: string,
stakeToken: string
stakeToken: string,
customOsp: string
): Promise<RollupCreator.RollupDeploymentParamsStruct> {
// set up owner address
const ownerAddress =
Expand Down Expand Up @@ -357,6 +363,7 @@ async function _getDevRollupConfig(
batchPosters: batchPosters,
batchPosterManager: batchPosterManager,
feeTokenPricer: feeTokenPricer,
customOsp: customOsp,
}

function _createValidatorAddress(
Expand Down
6 changes: 4 additions & 2 deletions scripts/upgrade/deploy4844.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async function main() {
const proverHostIo = await deployContract(
'OneStepProverHostIo',
signer,
[],
[ethers.constants.AddressZero],
false,
true,
overrides
Expand Down Expand Up @@ -96,7 +96,9 @@ async function main() {
await verifyContract('OneStepProver0', prover0.address, [])
await verifyContract('OneStepProverMemory', proverMem.address, [])
await verifyContract('OneStepProverMath', proverMath.address, [])
await verifyContract('OneStepProverHostIo', proverHostIo.address, [])
await verifyContract('OneStepProverHostIo', proverHostIo.address, [
ethers.constants.AddressZero,
])
await verifyContract('OneStepProofEntry', osp.address, [
prover0.address,
proverMem.address,
Expand Down
2 changes: 1 addition & 1 deletion slither.db.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/bridge/ISequencerInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ interface ISequencerInbox is IDelayedMessageProvider {
// solhint-disable-next-line func-name-mixedcase
function ZERO_HEAVY_MESSAGE_HEADER_FLAG() external view returns (bytes1);

/// @dev If the first data byte after the header has this set,
/// then the batch data comes from a custom data availability provider
// solhint-disable-next-line func-name-mixedcase
function CUSTOM_DA_MESSAGE_HEADER_FLAG() external view returns (bytes1);

function rollup() external view returns (IOwnable);

function isBatchPoster(
Expand Down
6 changes: 5 additions & 1 deletion src/bridge/SequencerInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
/// @inheritdoc ISequencerInbox
bytes1 public constant ZERO_HEAVY_MESSAGE_HEADER_FLAG = 0x20;

/// @inheritdoc ISequencerInbox
bytes1 public constant CUSTOM_DA_MESSAGE_HEADER_FLAG = 0x01;

// GAS_PER_BLOB from EIP-4844
uint256 internal constant GAS_PER_BLOB = 1 << 17;

Expand Down Expand Up @@ -599,7 +602,8 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
) internal pure returns (bool) {
return headerByte == BROTLI_MESSAGE_HEADER_FLAG || headerByte == DAS_MESSAGE_HEADER_FLAG
|| (headerByte == (DAS_MESSAGE_HEADER_FLAG | TREE_DAS_MESSAGE_HEADER_FLAG))
|| headerByte == ZERO_HEAVY_MESSAGE_HEADER_FLAG;
|| headerByte == ZERO_HEAVY_MESSAGE_HEADER_FLAG
|| headerByte == CUSTOM_DA_MESSAGE_HEADER_FLAG;
}

/// @dev Form a hash of the data taken from the calldata
Expand Down
43 changes: 43 additions & 0 deletions src/osp/ICustomDAProofValidator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2021-2024, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.0;

/**
* @title ICustomDAProofValidator
* @notice Interface for custom data availability proof validators
*/
interface ICustomDAProofValidator {
/**
* @notice Validates a custom DA proof and returns the preimage chunk
* @param certHash The keccak256 hash of the certificate (from machine's proven state)
* @param offset The offset into the preimage to read from (from machine's proven state)
* @param proof The proof data starting with [certSize(8), certificate, customData...]
* @return preimageChunk The 32-byte chunk of preimage data at the specified offset
*/
function validateReadPreimage(
bytes32 certHash,
uint256 offset,
bytes calldata proof
) external view returns (bytes memory preimageChunk);

/**
* @notice Validates whether a certificate is well-formed and legitimate
* @dev This function MUST NOT revert. It should return false for malformed or invalid certificates.
* The security model requires that the prover's validity claim matches what this function returns.
* If they disagree (e.g., prover claims valid but this returns false), the OSP will revert.
*
* The proof format is: [certSize(8), certificate, claimedValid(1), validityProof...]
* The validityProof section can contain additional verification data such as:
* - Cryptographic signatures
* - Merkle proofs
* - Timestamped attestations
* - Or other authentication mechanisms
* @param proof The proof data starting with [certSize(8), certificate, validityProof...]
* @return isValid True if the certificate is valid, false otherwise
*/
function validateCertificate(
bytes calldata proof
) external view returns (bool isValid);
}
3 changes: 2 additions & 1 deletion src/osp/OneStepProofEntry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ contract OneStepProofEntry is IOneStepProofEntry {
(
opcode >= Instructions.GET_GLOBAL_STATE_BYTES32
&& opcode <= Instructions.SET_GLOBAL_STATE_U64
) || (opcode >= Instructions.READ_PRE_IMAGE && opcode <= Instructions.UNLINK_MODULE)
)
|| (opcode >= Instructions.VALIDATE_CERTIFICATE && opcode <= Instructions.UNLINK_MODULE)
|| (opcode >= Instructions.NEW_COTHREAD && opcode <= Instructions.SWITCH_COTHREAD)
) {
prover = proverHostIo;
Expand Down
Loading
Loading