Commit b6a3a7d0 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into aj/cannon-dispute-by-agreeing

parents 916547cc 0eac68d1
......@@ -745,8 +745,7 @@ jobs:
- checkout
- run:
name: run lint
command: |
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
command: make lint
working_directory: <<parameters.module>>
go-test:
......@@ -842,7 +841,7 @@ jobs:
patterns: <<parameters.working_directory>>,<<parameters.dependencies>>
- run:
name: Lint
command: golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 2m -e "errors.As" -e "errors.Is" ./...
command: make lint
working_directory: <<parameters.working_directory>>
- store_test_results:
path: /test-results
......
......@@ -17,7 +17,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
fuzz:
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzChannelConfig_CheckTimeout ./batcher
......
......@@ -25,6 +25,9 @@ bindings-build:
-package $(pkg) \
-monorepo-base $(monorepo-base)
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
mkdir:
mkdir -p $(pkg)
......
GITCOMMIT := $(shell git rev-parse HEAD)
GITDATE := $(shell git show -s --format='%ct')
VERSION := v0.0.0
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
LDFLAGSSTRING +=-X main.GitDate=$(GITDATE)
LDFLAGSSTRING +=-X main.Version=$(VERSION)
LDFLAGS := -ldflags "$(LDFLAGSSTRING)"
op-bootnode:
env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/op-bootnode ./cmd
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
......@@ -6,6 +6,9 @@ check-l2:
test:
go test ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
fuzz:
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeWithdrawal ./crossdomain
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeLegacyWithdrawal ./crossdomain
......
......@@ -543,15 +543,36 @@ func checkOptimismMintableERC20Factory(addr common.Address, client *ethclient.Cl
return err
}
bridge, err := contract.BRIDGE(&bind.CallOpts{})
bridgeLegacy, err := contract.BRIDGE(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("OptimismMintableERC20Factory", "BRIDGE", bridge.Hex())
if bridge == (common.Address{}) {
log.Info("OptimismMintableERC20Factory", "BRIDGE", bridgeLegacy.Hex())
if bridgeLegacy == (common.Address{}) {
return errors.New("OptimismMintableERC20Factory.BRIDGE is zero address")
}
bridge, err := contract.Bridge(&bind.CallOpts{})
if err != nil {
return err
}
if bridge == (common.Address{}) {
return errors.New("OptimismMintableERC20Factory.bridge is zero address")
}
log.Info("OptimismMintableERC20Factory", "bridge", bridge.Hex())
initialized, err := getInitialized("OptimismMintableERC20Factory", addr, client)
if err != nil {
return err
}
log.Info("OptimismMintableERC20Factory", "_initialized", initialized)
initializing, err := getInitializing("OptimismMintableERC20Factory", addr, client)
if err != nil {
return err
}
log.Info("OptimismMintableERC20Factory", "_initializing", initializing)
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
......
......@@ -695,6 +695,11 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage
"_initialized": 2,
"_initializing": false,
}
storage["OptimismMintableERC20Factory"] = state.StorageValues{
"bridge": predeploys.L2StandardBridgeAddr,
"_initialized": 2,
"_initializing": false,
}
return storage, nil
}
......
......@@ -216,7 +216,7 @@ func l2Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep
}
_, tx, _, err = bindings.DeployL1FeeVault(opts, backend, recipient, minimumWithdrawalAmount, withdrawalNetwork)
case "OptimismMintableERC20Factory":
_, tx, _, err = bindings.DeployOptimismMintableERC20Factory(opts, backend, predeploys.L2StandardBridgeAddr)
_, tx, _, err = bindings.DeployOptimismMintableERC20Factory(opts, backend)
case "DeployerWhitelist":
_, tx, _, err = bindings.DeployDeployerWhitelist(opts, backend)
case "LegacyMessagePasser":
......
......@@ -17,7 +17,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
visualize:
./scripts/visualize.sh
......
......@@ -26,7 +26,7 @@ clean:
rm -r ../op-program/bin
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
.PHONY: \
test \
......
......@@ -38,7 +38,8 @@ func ForReceipt(ctx context.Context, client *ethclient.Client, hash common.Hash,
return nil, fmt.Errorf("failed to get receipt: %w", err)
}
if receipt.Status != status {
return receipt, addDebugTrace(ctx, client, hash, fmt.Errorf("expected status %d, but got %d", status, receipt.Status))
printDebugTrace(ctx, client, hash)
return receipt, fmt.Errorf("expected status %d, but got %d", status, receipt.Status)
}
return receipt, nil
}
......@@ -52,15 +53,16 @@ func (s *jsonRawString) UnmarshalJSON(input []byte) error {
return nil
}
// addDebugTrace adds debug_traceTransaction output to the original error to make debugging
func addDebugTrace(ctx context.Context, client *ethclient.Client, txHash common.Hash, origErr error) error {
var result jsonRawString
// printDebugTrace logs debug_traceTransaction output to aid in debugging unexpected receipt statuses
func printDebugTrace(ctx context.Context, client *ethclient.Client, txHash common.Hash) {
var trace jsonRawString
options := map[string]string{}
err := client.Client().CallContext(ctx, &result, "debug_traceTransaction", hexutil.Bytes(txHash.Bytes()), options)
err := client.Client().CallContext(ctx, &trace, "debug_traceTransaction", hexutil.Bytes(txHash.Bytes()), options)
if err != nil {
return errors.Join(origErr, fmt.Errorf("tx trace unavailable: %w", err))
fmt.Printf("TxTrace unavailable: %v\n", err)
return
}
return fmt.Errorf("%w\nTxTrace: %v", origErr, result)
fmt.Printf("TxTrace: %v\n", trace)
}
func ForBlock(ctx context.Context, client *ethclient.Client, n uint64) error {
......
......@@ -23,3 +23,6 @@ all: build
# Build binary
build:
CGO_ENABLED=0 go build $(LDFLAGS)
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
......@@ -17,7 +17,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
.PHONY: \
clean \
......
......@@ -18,7 +18,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
fuzz:
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzL1InfoRoundTrip ./rollup/derive
......
......@@ -31,7 +31,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
verify-goerli: op-program-host op-program-client
env GO111MODULE=on go run ./verify/cmd/goerli.go $$L1URL $$L2URL
......
......@@ -17,7 +17,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
.PHONY: \
clean \
......
......@@ -2,7 +2,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is" ./...
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
generate-mocks:
go generate ./...
......
GITCOMMIT := $(shell git rev-parse HEAD)
GITDATE := $(shell git show -s --format='%ct')
VERSION := v0.0.0
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
LDFLAGSSTRING +=-X main.GitDate=$(GITDATE)
LDFLAGSSTRING +=-X main.Version=$(VERSION)
LDFLAGS := -ldflags "$(LDFLAGSSTRING)"
op-wheel:
env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/op-wheel ./cmd
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
......@@ -423,10 +423,10 @@ OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11121)
OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140547)
OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9005)
OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163441)
OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 7646)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9401)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516769032)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1293594)
OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9760)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9471)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516769105)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1295838)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 11178)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16111)
OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26781)
......
......@@ -260,7 +260,10 @@
=======================
| Name | Type | Slot | Offset | Bytes | Contract |
|------|------|------|--------|-------|----------|
|---------------|---------|------|--------|-------|-----------------------------------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory |
| _initializing | bool | 0 | 1 | 1 | src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory |
| bridge | address | 0 | 2 | 20 | src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory |
=======================
➡ src/dispute/DisputeGameFactory.sol:DisputeGameFactory
......
......@@ -345,10 +345,10 @@ contract Deploy is Deployer {
/// @notice Deploy the OptimismMintableERC20Factory
function deployOptimismMintableERC20Factory() public broadcast returns (address addr_) {
address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(l1StandardBridgeProxy);
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory();
require(factory.BRIDGE() == l1StandardBridgeProxy);
require(factory.BRIDGE() == address(0));
require(factory.bridge() == address(0));
save("OptimismMintableERC20Factory", address(factory));
console.log("OptimismMintableERC20Factory deployed at %s", address(factory));
......@@ -613,9 +613,10 @@ contract Deploy is Deployer {
address optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20Factory");
address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
proxyAdmin.upgrade({
proxyAdmin.upgradeAndCall({
_proxy: payable(optimismMintableERC20FactoryProxy),
_implementation: optimismMintableERC20Factory
_implementation: optimismMintableERC20Factory,
_data: abi.encodeCall(OptimismMintableERC20Factory.initialize, (l1StandardBridgeProxy))
});
OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(optimismMintableERC20FactoryProxy);
......@@ -623,6 +624,7 @@ contract Deploy is Deployer {
console.log("OptimismMintableERC20Factory version: %s", version);
require(factory.BRIDGE() == l1StandardBridgeProxy);
require(factory.bridge() == l1StandardBridgeProxy);
}
/// @notice initializeL1CrossDomainMessenger
......
......@@ -25,7 +25,7 @@
"src/periphery/op-nft/OptimistAllowlist.sol": "0x53e9a9dfecbae036fd468e8f34c80c7d9c35bd8908c8a6483db44dbc5128ad69",
"src/periphery/op-nft/OptimistInviter.sol": "0xfdd5b9d45205ef9372ba37f7a6394724695e676d27a47cb154ee6e4148490013",
"src/universal/OptimismMintableERC20.sol": "0xa0b4f168802d0f9eca9ddc54347ca66c34ad7aa0fd84b01e0d7e99a9f86f46d6",
"src/universal/OptimismMintableERC20Factory.sol": "0x8afb6b634f40e8ac8c60ec7e2ca3bcd610b020d09b3cae70a3d4995722cab3ce",
"src/universal/OptimismMintableERC20Factory.sol": "0xf4beb7fed4defc3e70b2298831bf0024cceaa8f1cf55fd98c00f5998b8ab5589",
"src/universal/OptimismMintableERC721.sol": "0x49dc863caf3e002bf0c90b3af3873990fb282771f4c63735fd61a885b7873983",
"src/universal/OptimismMintableERC721Factory.sol": "0x502438b009bfaf0ab187914662468261f10446fd85d44a79b29cdaef7b4982ba"
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
pragma solidity 0.8.15;
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import { Semver } from "./Semver.sol";
/// @custom:proxied
......@@ -11,9 +12,10 @@ import { Semver } from "./Semver.sol";
/// contracts on the network it's deployed to. Simplifies the deployment process for users
/// who may be less familiar with deploying smart contracts. Designed to be backwards
/// compatible with the older StandardL2ERC20Factory contract.
contract OptimismMintableERC20Factory is Semver {
contract OptimismMintableERC20Factory is Semver, Initializable {
/// @notice Address of the StandardBridge on this chain.
address public immutable BRIDGE;
/// @custom:network-specific
address public bridge;
/// @custom:legacy
/// @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer
......@@ -28,13 +30,25 @@ contract OptimismMintableERC20Factory is Semver {
/// @param deployer Address of the account that deployed the token.
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
/// @custom:semver 1.2.0
/// @custom:semver 1.3.0
/// @notice The semver MUST be bumped any time that there is a change in
/// the OptimismMintableERC20 token contract since this contract
/// is responsible for deploying OptimismMintableERC20 contracts.
constructor() Semver(1, 3, 0) {
initialize({ _bridge: address(0) });
}
/// @notice Initializer.
/// @param _bridge Address of the StandardBridge on this chain.
constructor(address _bridge) Semver(1, 2, 0) {
BRIDGE = _bridge;
function initialize(address _bridge) public reinitializer(2) {
bridge = _bridge;
}
/// @notice Returns the address of the StandardBridge on this chain.
/// This is a legacy getter, use `bridge` instead.
/// @custom:legacy
function BRIDGE() external view returns (address) {
return bridge;
}
/// @custom:legacy
......@@ -71,7 +85,7 @@ contract OptimismMintableERC20Factory is Semver {
require(_remoteToken != address(0), "OptimismMintableERC20Factory: must provide remote token address");
bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol));
address localToken = address(new OptimismMintableERC20{salt: salt}(BRIDGE, _remoteToken, _name, _symbol));
address localToken = address(new OptimismMintableERC20{salt: salt}(bridge, _remoteToken, _name, _symbol));
// Emit the old event too for legacy support.
emit StandardL2TokenCreated(_remoteToken, localToken);
......
......@@ -377,17 +377,17 @@ contract Bridge_Initializer is Messenger_Initializer {
vm.label(address(L1Bridge_Impl), "L1StandardBridge_Impl");
// Deploy the L2StandardBridge, move it to the correct predeploy
// address and then initialize it
// address and then initialize it. It is safe to call initialize directly
// on the proxy because the bytecode was set in state with `etch`.
vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(proxy)))).code);
L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));
L2Bridge.initialize();
// Set up the L2 mintable token factory
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(
Predeploys.L2_STANDARD_BRIDGE
);
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory();
vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);
L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);
L2TokenFactory.initialize(Predeploys.L2_STANDARD_BRIDGE);
vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);
......@@ -419,7 +419,15 @@ contract Bridge_Initializer is Messenger_Initializer {
);
NativeL2Token = new ERC20("Native L2 Token", "L2T");
L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));
Proxy factoryProxy = new Proxy(multisig);
OptimismMintableERC20Factory L1TokenFactoryImpl = new OptimismMintableERC20Factory();
vm.prank(multisig);
factoryProxy.upgradeToAndCall(
address(L1TokenFactoryImpl), abi.encodeCall(OptimismMintableERC20Factory.initialize, address(L1Bridge))
);
L1TokenFactory = OptimismMintableERC20Factory(address(factoryProxy));
RemoteL1Token = OptimismMintableERC20(
L1TokenFactory.createStandardL2Token(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment