Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -923,8 +923,8 @@ jobs:
command: semgrep
- run-contracts-check:
command: semver-lock-no-build
- run-contracts-check:
command: semver-diff-check-no-build
#- run-contracts-check:
#command: semver-diff-check-no-build
- run-contracts-check:
command: validate-deploy-configs
- run-contracts-check:
Expand Down
11 changes: 6 additions & 5 deletions op-chain-ops/solc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ type CompilerInput struct {
}

type CompilerSettings struct {
Optimizer OptimizerSettings `json:"optimizer"`
Metadata CompilerInputMetadata `json:"metadata"`
OutputSelection map[string]map[string][]string `json:"outputSelection"`
EvmVersion string `json:"evmVersion,omitempty"`
Libraries map[string]map[string]string `json:"libraries,omitempty"`
Optimizer OptimizerSettings `json:"optimizer"`
Metadata CompilerInputMetadata `json:"metadata"`
CompilationTarget map[string]string `json:"compilationTarget"`
OutputSelection map[string]map[string][]string `json:"outputSelection"`
EvmVersion string `json:"evmVersion,omitempty"`
Libraries map[string]map[string]string `json:"libraries,omitempty"`
}

type OptimizerSettings struct {
Expand Down
1 change: 1 addition & 0 deletions packages/contracts-bedrock/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ snapshots = 'notarealpath' # workaround for foundry#9477

optimizer = true
optimizer_runs = 999999
use_literal_content = true

# IMPORTANT:
# When adding any new compiler profiles or compilation restrictions, you must
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"encoding/json"
"fmt"
"os"
"regexp"
"sort"
"strings"

"github.com/ethereum-optimism/optimism/op-chain-ops/solc"
"github.com/ethereum-optimism/optimism/packages/contracts-bedrock/scripts/checks/common"
"github.com/ethereum/go-ethereum/crypto"
)
Expand All @@ -21,8 +21,8 @@ type SemverLockOutput struct {
}

type SemverLockResult struct {
SemverLockOutput
SourceFilePath string
ContractKey string
SemverLockOutput SemverLockOutput
}

func main() {
Expand All @@ -32,7 +32,7 @@ func main() {
processFile,
)
if err != nil {
fmt.Printf("error: %v\n", err)
fmt.Printf("Failed to generate semver lock: %v\n", err)
os.Exit(1)
}

Expand All @@ -42,7 +42,7 @@ func main() {
if result == nil {
continue
}
output[result.SourceFilePath] = result.SemverLockOutput
output[result.ContractKey] = result.SemverLockOutput
}

// Get and sort the keys
Expand Down Expand Up @@ -76,16 +76,60 @@ func processFile(file string) (*SemverLockResult, []error) {
return nil, []error{fmt.Errorf("failed to read artifact: %w", err)}
}

var sourceFilePath, contractName, contractKey string
for path, name := range artifact.Metadata.Settings.CompilationTarget {
sourceFilePath = path
contractName = name
contractKey = sourceFilePath + ":" + name
break
}

// Only apply to files in the src directory.
sourceFilePath := artifact.Ast.AbsolutePath
if !strings.HasPrefix(sourceFilePath, "src/") {
return nil, nil
}

// Check if the contract uses semver.
semverRegex := regexp.MustCompile(`custom:semver`)
semver := semverRegex.FindStringSubmatch(artifact.RawMetadata)
if len(semver) == 0 {
// Check if the contract has a version function or variable with @custom:semver tag
hasSemverTag := false
for _, node := range artifact.Ast.Nodes {
if node.NodeType != "ContractDefinition" || node.Name != contractName {
continue
}
// Check each node inside the contract
for _, subNode := range node.Nodes {
// Skip nodes that aren't version functions or variables
if (subNode.NodeType != "FunctionDefinition" &&
subNode.NodeType != "VariableDeclaration") ||
subNode.Name != "version" {
continue
}
if subNode.Documentation == nil {
continue
}
// Handle documentation based on its actual type
var docText string
switch doc := subNode.Documentation.(type) {
case string:
docText = doc
case map[string]interface{}:
if text, ok := doc["text"].(string); ok {
docText = text
}
case solc.AstDocumentation:
docText = doc.Text
case *solc.AstDocumentation:
docText = doc.Text
}
if strings.Contains(docText, "@custom:semver") {
hasSemverTag = true
break
}
}
if hasSemverTag {
break
}
}
if !hasSemverTag {
return nil, nil
}

Expand All @@ -101,13 +145,12 @@ func processFile(file string) (*SemverLockResult, []error) {
return nil, []error{fmt.Errorf("failed to read source file: %w", err)}
}

// Calculate hashes using Keccak256
trimmedSourceCode := []byte(strings.TrimSuffix(string(sourceCode), "\n"))
initCodeHash := fmt.Sprintf("0x%x", crypto.Keccak256Hash(initCodeBytes))
sourceCodeHash := fmt.Sprintf("0x%x", crypto.Keccak256Hash(trimmedSourceCode))

return &SemverLockResult{
SourceFilePath: sourceFilePath,
ContractKey: contractKey,
SemverLockOutput: SemverLockOutput{
InitCodeHash: initCodeHash,
SourceCodeHash: sourceCodeHash,
Expand Down
120 changes: 60 additions & 60 deletions packages/contracts-bedrock/scripts/checks/check-frozen-files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,66 +48,66 @@ changed_contracts=$(jq -r '
# In order to prevent a file from being modified, comment it out. Do not delete it.
# All files in semver-lock.json should be in this list.
ALLOWED_FILES=(
"src/L1/DataAvailabilityChallenge.sol"
"src/L1/L1CrossDomainMessenger.sol"
"src/L1/L1ERC721Bridge.sol"
"src/L1/L1StandardBridge.sol"
"src/L1/OPContractsManager.sol"
"src/L1/OPContractsManagerInterop.sol"
"src/L1/OPPrestateUpdater.sol"
"src/L1/OptimismPortal2.sol"
"src/L1/OptimismPortalInterop.sol"
"src/L1/ProtocolVersions.sol"
"src/L1/SuperchainConfig.sol"
"src/L1/SystemConfig.sol"
"src/L1/SystemConfigInterop.sol"
"src/L2/BaseFeeVault.sol"
"src/L2/CrossL2Inbox.sol"
"src/L2/ETHLiquidity.sol"
"src/L2/GasPriceOracle.sol"
"src/L2/L1Block.sol"
"src/L2/L1BlockInterop.sol"
"src/L2/L1FeeVault.sol"
"src/L2/L2CrossDomainMessenger.sol"
"src/L2/L2ERC721Bridge.sol"
"src/L2/L2StandardBridge.sol"
"src/L2/L2StandardBridgeInterop.sol"
"src/L2/L2ToL1MessagePasser.sol"
"src/L2/L2ToL2CrossDomainMessenger.sol"
"src/L2/OptimismMintableERC721.sol"
"src/L2/OptimismMintableERC721Factory.sol"
"src/L2/OptimismSuperchainERC20.sol"
"src/L2/OptimismSuperchainERC20Beacon.sol"
"src/L2/OptimismSuperchainERC20Factory.sol"
"src/L2/SequencerFeeVault.sol"
"src/L2/SuperchainERC20.sol"
"src/L2/SuperchainTokenBridge.sol"
"src/L2/SuperchainWETH.sol"
"src/L2/WETH.sol"
"src/cannon/MIPS.sol"
"src/cannon/MIPS2.sol"
"src/cannon/MIPS64.sol"
"src/cannon/PreimageOracle.sol"
"src/dispute/AnchorStateRegistry.sol"
"src/dispute/DelayedWETH.sol"
"src/dispute/DisputeGameFactory.sol"
"src/dispute/FaultDisputeGame.sol"
"src/dispute/PermissionedDisputeGame.sol"
"src/dispute/SuperFaultDisputeGame.sol"
"src/dispute/SuperPermissionedDisputeGame.sol"
"src/legacy/DeployerWhitelist.sol"
"src/legacy/L1BlockNumber.sol"
"src/legacy/LegacyMessagePasser.sol"
"src/safe/DeputyGuardianModule.sol"
"src/safe/DeputyPauseModule.sol"
"src/safe/LivenessGuard.sol"
"src/safe/LivenessModule.sol"
"src/universal/OptimismMintableERC20.sol"
"src/universal/OptimismMintableERC20Factory.sol"
"src/universal/StorageSetter.sol"
"src/vendor/asterisc/RISCV.sol"
"src/vendor/eas/EAS.sol"
"src/vendor/eas/SchemaRegistry.sol"
"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge"
"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger"
"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge"
"src/L1/L1StandardBridge.sol:L1StandardBridge"
"src/L1/OPContractsManager.sol:OPContractsManager"
"src/L1/OPContractsManagerInterop.sol:OPContractsManagerInterop"
"src/L1/OPPrestateUpdater.sol:OPPrestateUpdater"
"src/L1/OptimismPortal2.sol:OptimismPortal2"
"src/L1/OptimismPortalInterop.sol:OptimismPortalInterop"
"src/L1/ProtocolVersions.sol:ProtocolVersions"
"src/L1/SuperchainConfig.sol:SuperchainConfig"
"src/L1/SystemConfig.sol:SystemConfig"
"src/L1/SystemConfigInterop.sol:SystemConfigInterop"
"src/L2/BaseFeeVault.sol:BaseFeeVault"
"src/L2/CrossL2Inbox.sol:CrossL2Inbox"
"src/L2/ETHLiquidity.sol:ETHLiquidity"
"src/L2/GasPriceOracle.sol:GasPriceOracle"
"src/L2/L1Block.sol:L1Block"
"src/L2/L1BlockInterop.sol:L1BlockInterop"
"src/L2/L1FeeVault.sol:L1FeeVault"
"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger"
"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge"
"src/L2/L2StandardBridge.sol:L2StandardBridge"
"src/L2/L2StandardBridgeInterop.sol:L2StandardBridgeInterop"
"src/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser"
"src/L2/L2ToL2CrossDomainMessenger.sol:L2ToL2CrossDomainMessenger"
"src/L2/OptimismMintableERC721.sol:OptimismMintableERC721"
"src/L2/OptimismMintableERC721Factory.sol:OptimismMintableERC721Factory"
"src/L2/OptimismSuperchainERC20.sol:OptimismSuperchainERC20"
"src/L2/OptimismSuperchainERC20Beacon.sol:OptimismSuperchainERC20Beacon"
"src/L2/OptimismSuperchainERC20Factory.sol:OptimismSuperchainERC20Factory"
"src/L2/SequencerFeeVault.sol:SequencerFeeVault"
"src/L2/SuperchainERC20.sol:SuperchainERC20"
"src/L2/SuperchainTokenBridge.sol:SuperchainTokenBridge"
"src/L2/SuperchainWETH.sol:SuperchainWETH"
"src/L2/WETH.sol:WETH"
"src/cannon/MIPS.sol:MIPS"
"src/cannon/MIPS2.sol:MIPS2"
"src/cannon/MIPS64.sol:MIPS64"
"src/cannon/PreimageOracle.sol:PreimageOracle"
"src/dispute/AnchorStateRegistry.sol:AnchorStateRegistry"
"src/dispute/DelayedWETH.sol:DelayedWETH"
"src/dispute/DisputeGameFactory.sol:DisputeGameFactory"
"src/dispute/FaultDisputeGame.sol:FaultDisputeGame"
"src/dispute/PermissionedDisputeGame.sol:PermissionedDisputeGame"
"src/dispute/SuperFaultDisputeGame.sol:SuperFaultDisputeGame"
"src/dispute/SuperPermissionedDisputeGame.sol:SuperPermissionedDisputeGame"
"src/legacy/DeployerWhitelist.sol:DeployerWhitelist"
"src/legacy/L1BlockNumber.sol:L1BlockNumber"
"src/legacy/LegacyMessagePasser.sol:LegacyMessagePasser"
"src/safe/DeputyGuardianModule.sol:DeputyGuardianModule"
"src/safe/DeputyPauseModule.sol:DeputyPauseModule"
"src/safe/LivenessGuard.sol:LivenessGuard"
"src/safe/LivenessModule.sol:LivenessModule"
"src/universal/OptimismMintableERC20.sol:OptimismMintableERC20"
"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory"
"src/universal/StorageSetter.sol:StorageSetter"
"src/vendor/asterisc/RISCV.sol:RISCV"
"src/vendor/eas/EAS.sol:EAS"
"src/vendor/eas/SchemaRegistry.sol:SchemaRegistry"
)

MATCHED_FILES=()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ changed_contracts=$(jq -r '
.key as $key
| .value != $upstream[$key]
)
) | map(.key);
) | map(.key | split(":")[0]);
changes[]
' "$temp_dir/local_semver_lock.json" "$temp_dir/upstream_semver_lock.json")

Expand Down
Loading