Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions synd-contracts/src/staking/GasAggregator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ contract GasAggregator is Ownable(msg.sender), Pausable, EpochTracker {
/// @param maxAppchainsToQuery The new maximum number of appchains to query
event UpdateMaxAppchainsToQuery(uint256 indexed epoch, uint256 maxAppchainsToQuery);

/// @notice Emitted when the factory address and bytecode is set
/// @param factoryAddress The address of the factory contract
/// @param bytecodeHash The bytecode hash of the proxy that the factory deploys
event FactorySet(address indexed factoryAddress, bytes32 bytecodeHash);

/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -384,6 +389,7 @@ contract GasAggregator is Ownable(msg.sender), Pausable, EpochTracker {
require(bytecodeHash != 0, InvalidDataHash());
factory = newFactory;
syndicateProxyBytecodeHash = bytecodeHash;
emit FactorySet(newFactory, bytecodeHash);
}

/**
Expand Down
24 changes: 12 additions & 12 deletions synd-contracts/src/staking/GasArchive.sol
Original file line number Diff line number Diff line change
Expand Up @@ -291,18 +291,18 @@ contract GasArchive is Initializable, OwnableUpgradeable, IGasDataProvider, UUPS
/// @dev Verifies the proof data of the sequencing chain's proof against the confirmed seq chain block hash
/// @param seqChainID The sequencing chain ID
/// @param sendRoot The send root stored in the the Arbitrum Outbox contract that the eth proof was generated for, unused if seqChainID == settlementChainID
/// @param ethBlockHeader RLP-encoded Ethereum block header, unused if seqChainID == settlementChainID
/// @param ethAccountProof Merkle proof of the bridge contract account, unused if seqChainID == settlementChainID
/// @param ethStorageProof Merkle proof of the storage slot containing the block hash, unused if seqChainID == settlementChainID
/// @param seqParentBlockHeader RLP-encoded block header of the parent chain of the sequencing chain, unused if seqChainID == settlementChainID
/// @param seqParentAccountProof Merkle proof of the bridge contract account, unused if seqChainID == settlementChainID
/// @param seqParentStorageProof Merkle proof of the storage slot containing the block hash, unused if seqChainID == settlementChainID
/// @param seqBlockHeader RLP-encoded sequencing chain block header
/// @param seqAccountProof Merkle proof of the GasAggregator account
/// @param seqStorageProof Merkle proof of the epoch data storage slot
function confirmEpochDataHash(
uint256 seqChainID,
bytes32 sendRoot,
bytes calldata ethBlockHeader,
bytes[] calldata ethAccountProof,
bytes[] calldata ethStorageProof,
bytes calldata seqParentBlockHeader,
bytes[] calldata seqParentAccountProof,
bytes[] calldata seqParentStorageProof,
bytes calldata seqBlockHeader,
bytes[] calldata seqAccountProof,
bytes[] calldata seqStorageProof
Expand All @@ -315,15 +315,15 @@ contract GasArchive is Initializable, OwnableUpgradeable, IGasDataProvider, UUPS
}

if ($.seqChainSettlesToBase[seqChainID]) {
require($.setBlockHashes[keccak256(ethBlockHeader)], InvalidSetBlockHeader());
require($.setBlockHashes[keccak256(seqParentBlockHeader)], InvalidSetBlockHeader());
} else {
require($.ethBlockHashes[keccak256(ethBlockHeader)], InvalidEthBlockHeader());
require($.ethBlockHashes[keccak256(seqParentBlockHeader)], InvalidEthBlockHeader());
}

bytes32 verifiedSeqChainBlockHash = _getSlotValueFromProof({
blockHeader: ethBlockHeader,
accountProof: ethAccountProof,
storageProof: ethStorageProof,
blockHeader: seqParentBlockHeader,
accountProof: seqParentAccountProof,
storageProof: seqParentStorageProof,
account: $.seqChainOutbox[seqChainID],
storageSlot: keccak256(abi.encode(sendRoot, SEND_ROOT_STORAGE_SLOT))
});
Expand Down Expand Up @@ -427,7 +427,7 @@ contract GasArchive is Initializable, OwnableUpgradeable, IGasDataProvider, UUPS
stack: _RLPItemsFromProofBytes(accountProof)
}).toRlpItem();

// If the account does not exist, return the hash of an empty trie.
// If the account does not exist in the proof, revert with AccountDoesNotExistInProof error.
require(accountRlp.len > 0, AccountDoesNotExistInProof());

RLPReader.RLPItem memory slotContents = MerklePatriciaProofVerifier.extractProofValue({
Expand Down
10 changes: 5 additions & 5 deletions synd-contracts/src/staking/STAKING_EMISSIONS_AUDIT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ bytes32 public syndicateProxyBytecodeHash;

#### Key Functions:

##### `addChain(uint256 chainId, uint256 addChainFee)`
##### `addChain(uint256 chainId) external payable`
- Registers an appchain for gas tracking
- Requires fee payment in SYND tokens
- Only called by authorized appchain contracts
- Permissionless: anyone can call by paying the required fee (owner pays no fee)
- Chain must exist at deterministic CREATE2 address (verified via factory + bytecode hash)

##### `aggregateTokensUsed(uint256 epochIndex, uint256[] calldata chainIds, uint256[] calldata tokensUsed)`
- Aggregates gas usage for completed epochs
Expand Down Expand Up @@ -634,8 +634,8 @@ deposit(epochIndex) with 1001 ETH:
- **Anyone**: Can submit proofs and epoch data (permissionless validation)

#### GasAggregator:
- **Owner**: Can pause, set factory, manage parameters
- **Appchains**: Can add themselves (with fee payment)
- **Owner**: Can pause, set factory, manage parameters, add/remove chains without fee
- **Anyone**: Can register chains by paying the `addChainFee` (chain must exist at deterministic address)
- **Anyone**: Can aggregate completed epoch data

#### Reward Pools:
Expand Down
Loading