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

Merge branch 'develop' into clabby/op-challenger-devnet-hack

parents 5a364314 29c1f395
......@@ -861,8 +861,8 @@ jobs:
make devnet-up-deploy
- run:
name: Check L2 config
command: npx hardhat check-l2 --network devnetL1 --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory: packages/contracts-bedrock
command: go run cmd/check-l2/main.go --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory: op-chain-ops
- run:
name: Deposit ERC20 through the bridge
command: timeout 8m npx hardhat deposit-erc20 --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json
......@@ -907,13 +907,8 @@ jobs:
make devnet-up
- run:
name: Check L2 config
command: |
npx hardhat check-l2 \
--network devnetL1 \
--l2-rpc-url http://localhost:9545 \
--l1-rpc-url http://localhost:8545 \
--l2-output-oracle-address 0x6900000000000000000000000000000000000000
working_directory: packages/contracts-bedrock
command: go run cmd/check-l2/main.go --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory: op-chain-ops
- run:
name: Deposit ERC20 through the bridge
command: timeout 10m npx hardhat deposit-erc20 --network devnetL1
......
......@@ -32,6 +32,7 @@ bindings: l1block-bindings \
basefee-vault-bindings \
legacy-erc20-eth-bindings \
dispute-game-factory-bindings \
fault-dispute-game-bindings \
standard-bridge-bindings \
cross-domain-messenger-bindings \
cannon-mips \
......@@ -130,6 +131,9 @@ l1-blocknumber-bindings: compile
dispute-game-factory-bindings: compile
./gen_bindings.sh contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory $(pkg)
fault-dispute-game-bindings: compile
./gen_bindings.sh contracts/dispute/FaultDisputeGame.sol:FaultDisputeGame $(pkg)
standard-bridge-bindings: compile
./gen_bindings.sh contracts/universal/StandardBridge.sol:StandardBridge $(pkg)
......
This diff is collapsed.
This diff is collapsed.
......@@ -21,7 +21,7 @@ var (
// l1PredeployNamespace represents the namespace of L1 predeploys
l1PredeployNamespace = common.HexToAddress("0x6900000000000000000000000000000000000000")
// bigL2PredeployNamespace represents the predeploy namespace as a big.Int
bigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes())
BigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes())
// bigL1PredeployNamespace represents the predeploy namespace as a big.Int
bigL1PredeployNamespace = new(big.Int).SetBytes(l1PredeployNamespace.Bytes())
// bigCodeNamespace represents the predeploy namespace as a big.Int
......
......@@ -36,7 +36,7 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene
}
// Set up the proxies
err = setProxies(db, predeploys.ProxyAdminAddr, bigL2PredeployNamespace, 2048)
err = setProxies(db, predeploys.ProxyAdminAddr, BigL2PredeployNamespace, 2048)
if err != nil {
return nil, err
}
......
package util
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/rpc"
"github.com/urfave/cli/v2"
)
var (
// EIP1976ImplementationSlot
EIP1967ImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc")
// EIP1967AdminSlot
EIP1967AdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103")
)
// clients represents a set of initialized RPC clients
type Clients struct {
L1Client *ethclient.Client
L2Client *ethclient.Client
L1RpcClient *rpc.Client
L2RpcClient *rpc.Client
L1GethClient *gethclient.Client
L2GethClient *gethclient.Client
}
// NewClients will create new RPC clients from a CLI context
func NewClients(ctx *cli.Context) (*Clients, error) {
clients := Clients{}
l1RpcURL := ctx.String("l1-rpc-url")
if l1RpcURL != "" {
l1Client, l1RpcClient, l1GethClient, err := newClients(l1RpcURL)
if err != nil {
return nil, err
}
clients.L1Client = l1Client
clients.L1RpcClient = l1RpcClient
clients.L1GethClient = l1GethClient
}
l2RpcURL := ctx.String("l2-rpc-url")
if l2RpcURL != "" {
l2Client, l2RpcClient, l2GethClient, err := newClients(l2RpcURL)
if err != nil {
return nil, err
}
clients.L2Client = l2Client
clients.L2RpcClient = l2RpcClient
clients.L2GethClient = l2GethClient
}
return &clients, nil
}
// newClients will create new clients from a given URL
func newClients(url string) (*ethclient.Client, *rpc.Client, *gethclient.Client, error) {
ethClient, err := ethclient.Dial(url)
if err != nil {
return nil, nil, nil, fmt.Errorf("cannot dial ethclient: %w", err)
}
rpcClient, err := rpc.DialContext(context.Background(), url)
if err != nil {
return nil, nil, nil, fmt.Errorf("cannot dial rpc client: %w", err)
}
return ethClient, rpcClient, gethclient.New(rpcClient), nil
}
// ClientsFlags represent the flags associated with creating RPC clients.
var ClientsFlags = []cli.Flag{
&cli.StringFlag{
Name: "l1-rpc-url",
Required: true,
Usage: "L1 RPC URL",
EnvVars: []string{"L1_RPC_URL"},
},
&cli.StringFlag{
Name: "l2-rpc-url",
Required: true,
Usage: "L2 RPC URL",
EnvVars: []string{"L2_RPC_URL"},
},
}
// Addresses represents the address values of various contracts. The values can
// be easily populated via a [cli.Context].
type Addresses struct {
AddressManager common.Address
OptimismPortal common.Address
L1StandardBridge common.Address
L1CrossDomainMessenger common.Address
CanonicalTransactionChain common.Address
StateCommitmentChain common.Address
}
// AddressesFlags represent the flags associated with address parsing.
var AddressesFlags = []cli.Flag{
&cli.StringFlag{
Name: "address-manager-address",
Usage: "AddressManager address",
EnvVars: []string{"ADDRESS_MANAGER_ADDRESS"},
},
&cli.StringFlag{
Name: "optimism-portal-address",
Usage: "OptimismPortal address",
EnvVars: []string{"OPTIMISM_PORTAL_ADDRESS"},
},
&cli.StringFlag{
Name: "l1-standard-bridge-address",
Usage: "L1StandardBridge address",
EnvVars: []string{"L1_STANDARD_BRIDGE_ADDRESS"},
},
&cli.StringFlag{
Name: "l1-crossdomain-messenger-address",
Usage: "L1CrossDomainMessenger address",
EnvVars: []string{"L1_CROSSDOMAIN_MESSENGER_ADDRESS"},
},
&cli.StringFlag{
Name: "canonical-transaction-chain-address",
Usage: "CanonicalTransactionChain address",
EnvVars: []string{"CANONICAL_TRANSACTION_CHAIN_ADDRESS"},
},
&cli.StringFlag{
Name: "state-commitment-chain-address",
Usage: "StateCommitmentChain address",
EnvVars: []string{"STATE_COMMITMENT_CHAIN_ADDRESS"},
},
}
// NewAddresses populates an Addresses struct given a [cli.Context].
// This is useful for writing scripts that interact with smart contracts.
func NewAddresses(ctx *cli.Context) (*Addresses, error) {
var addresses Addresses
var err error
addresses.AddressManager, err = parseAddress(ctx, "address-manager-address")
if err != nil {
return nil, err
}
addresses.OptimismPortal, err = parseAddress(ctx, "optimism-portal-address")
if err != nil {
return nil, err
}
addresses.L1StandardBridge, err = parseAddress(ctx, "l1-standard-bridge-address")
if err != nil {
return nil, err
}
addresses.L1CrossDomainMessenger, err = parseAddress(ctx, "l1-crossdomain-messenger-address")
if err != nil {
return nil, err
}
addresses.CanonicalTransactionChain, err = parseAddress(ctx, "canonical-transaction-chain-address")
if err != nil {
return nil, err
}
addresses.StateCommitmentChain, err = parseAddress(ctx, "state-commitment-chain-address")
if err != nil {
return nil, err
}
return &addresses, nil
}
// parseAddress will parse a [common.Address] from a [cli.Context] and return
// an error if the configured address is not correct.
func parseAddress(ctx *cli.Context, name string) (common.Address, error) {
value := ctx.String(name)
if value == "" {
return common.Address{}, nil
}
if !common.IsHexAddress(value) {
return common.Address{}, fmt.Errorf("invalid address: %s", value)
}
return common.HexToAddress(value), nil
}
......@@ -2,6 +2,7 @@ package preimage
import (
"encoding/binary"
"encoding/hex"
"fmt"
"io"
)
......@@ -57,7 +58,7 @@ func (o *OracleServer) NextPreimageRequest(getPreimage PreimageGetter) error {
}
value, err := getPreimage(key)
if err != nil {
return fmt.Errorf("failed to serve pre-image %s request: %w", key, err)
return fmt.Errorf("failed to serve pre-image %s request: %w", hex.EncodeToString(key[:]), err)
}
if err := binary.Write(o.rw, binary.BigEndian, uint64(len(value))); err != nil {
......
......@@ -114,6 +114,7 @@ func Run(l1RpcUrl string, l2RpcUrl string, l2OracleAddr common.Address) error {
}()
fmt.Printf("Using temp dir: %s\n", temp)
args := []string{
"--log.level", "DEBUG",
"--network", "goerli",
"--exec", "./bin/op-program-client",
"--datadir", temp,
......
......@@ -32,30 +32,30 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 502842)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 504699)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 492706)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 501717)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 503574)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 491581)
FaultDisputeGame_Test:test_defendRoot_invalidMove_reverts() (gas: 13250)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17448)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17873)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10337)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8216)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 498826)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 500705)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 488169)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 497701)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 499580)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 487044)
FaultDisputeGame_Test:test_defendRoot_invalidMove_reverts() (gas: 13294)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17426)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17917)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10315)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8282)
FaultDisputeGame_Test:test_initialRootClaimData_succeeds() (gas: 17691)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 26410)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 103231)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 407967)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 26387)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 103230)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 408100)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10923)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24632)
FaultDisputeGame_Test:test_resolve_challengeContested() (gas: 221068)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9657)
FaultDisputeGame_Test:test_resolve_rootContested() (gas: 106120)
FaultDisputeGame_Test:test_resolve_rootUncontested() (gas: 23624)
FaultDisputeGame_Test:test_resolve_teamDeathmatch() (gas: 391731)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8203)
FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107322)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24655)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 221201)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9679)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 106068)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 23692)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 391875)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8181)
FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107388)
FeeVault_Test:test_constructor_succeeds() (gas: 18185)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352135)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950342)
......
......@@ -72,12 +72,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @inheritdoc IFaultDisputeGame
function attack(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, true);
move(_parentIndex, _pivot, true);
}
/// @inheritdoc IFaultDisputeGame
function defend(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, false);
move(_parentIndex, _pivot, false);
}
/// @inheritdoc IFaultDisputeGame
......@@ -162,11 +162,11 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @param _challengeIndex The index of the claim being moved against.
/// @param _pivot The claim at the next logical position in the game.
/// @param _isAttack Whether or not the move is an attack or defense.
function _move(
function move(
uint256 _challengeIndex,
Claim _pivot,
bool _isAttack
) internal {
) public payable {
// Moves cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) {
revert GameNotInProgress();
......@@ -254,6 +254,11 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
l2BlockNumber_ = _getArgUint256(0x20);
}
/// @notice Returns the length of the `claimData` array.
function claimDataLen() external view returns (uint256 len_) {
len_ = claimData.length;
}
////////////////////////////////////////////////////////////////
// `IDisputeGame` impl //
////////////////////////////////////////////////////////////////
......
......@@ -236,7 +236,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontested() public {
function test_resolve_rootUncontested_succeeds() public {
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
......@@ -260,7 +260,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
/// @dev Static unit test for the correctness of resolving a single attack game state.
function test_resolve_rootContested() public {
function test_resolve_rootContested_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
GameStatus status = gameProxy.resolve();
......@@ -269,7 +269,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
/// @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
function test_resolve_challengeContested() public {
function test_resolve_challengeContested_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
......@@ -279,7 +279,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
/// @dev Static unit test for the correctness of resolving a game with multiplayer moves.
function test_resolve_teamDeathmatch() public {
function test_resolve_teamDeathmatch_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(0, Claim.wrap(bytes32(uint256(4))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
......@@ -391,7 +391,7 @@ contract GamePlayer {
// Now, search for the index of the claim that commits to the prestate's trace
// index.
uint256 len = claimDataLen();
uint256 len = gameProxy.claimDataLen();
for (uint256 i = 0; i < len; i++) {
(, , , Position pos, ) = gameProxy.claimData(i);
if (Position.unwrap(pos) == Position.unwrap(statePos)) {
......@@ -424,7 +424,7 @@ contract GamePlayer {
// Attack the parent claim.
gameProxy.attack(_parentIndex, ourClaim);
// Call out to our counter party to respond.
counterParty.play(claimDataLen() - 1);
counterParty.play(gameProxy.claimDataLen() - 1);
// If we have a second move position, attack the grandparent.
if (Position.unwrap(movePos2) != 0) {
......@@ -432,22 +432,17 @@ contract GamePlayer {
Claim ourGrandparentClaim = claimAt(grandparentPos.move(true));
gameProxy.attack(grandparentIndex, ourGrandparentClaim);
counterParty.play(claimDataLen() - 1);
counterParty.play(gameProxy.claimDataLen() - 1);
}
} else {
// Defend the parent claim.
gameProxy.defend(_parentIndex, ourClaim);
// Call out to our counter party to respond.
counterParty.play(claimDataLen() - 1);
counterParty.play(gameProxy.claimDataLen() - 1);
}
}
}
/// @notice Returns the length of the claim data array.
function claimDataLen() internal view returns (uint256 len_) {
return uint256(vm.load(address(gameProxy), bytes32(uint256(1))));
}
/// @notice Returns the state at the trace index within the player's trace.
function traceAt(Position _position) public view returns (uint256 state_) {
return traceAt(_position.traceIndex(maxDepth));
......
This diff is collapsed.
import './solidity'
import './check-l2'
import './generate-deploy-config'
......@@ -17,8 +17,6 @@
- [Configuration](#configuration)
- [Security Considerations](#security-considerations)
- [L1 Reorgs](#l1-reorgs)
- [Summary of Definitions](#summary-of-definitions)
- [Constants](#constants)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
......@@ -225,12 +223,3 @@ If the L1 has a reorg after an output has been generated and submitted, the L2 s
leading to a faulty proposal. This is mitigated against by allowing the proposer to submit an
L1 block number and hash to the Output Oracle when appending a new output; in the event of a reorg, the block hash
will not match that of the block with that number and the call will revert.
## Summary of Definitions
### Constants
| Name | Value | Unit |
| --------------------- | ------- | ------- |
| `SUBMISSION_INTERVAL` | `120` | blocks |
| `L2_BLOCK_TIME` | `2` | seconds |
......@@ -48,8 +48,6 @@ finalization.
- [Security Considerations](#security-considerations)
- [Key Properties of Withdrawal Verification](#key-properties-of-withdrawal-verification)
- [Handling Successfully Verified Messages That Fail When Relayed](#handling-successfully-verified-messages-that-fail-when-relayed)
- [Summary of Definitions](#summary-of-definitions)
- [Constants](#constants)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
......@@ -216,15 +214,5 @@ whether or not it was 'supposed' to fail, and whether or not it should be 'repla
minimize complexity, we have not provided any replay functionality, this may be implemented in external utility
contracts if desired.
## Summary of Definitions
### Constants
| Name | Value | Unit |
| --------------------- | --------- | ------- |
| `FINALIZATION_PERIOD` | `604_800` | seconds |
This `FINALIZATION_PERIOD` value is equivalent to 7 days.
[`WithdrawalTransaction` type]: https://github.com/ethereum-optimism/optimism/blob/6c6d142d7bb95faa11066aab5d8aed7187abfe38/packages/contracts-bedrock/contracts/libraries/Types.sol#L76-L83
[`OutputRootProof` type]: https://github.com/ethereum-optimism/optimism/blob/6c6d142d7bb95faa11066aab5d8aed7187abfe38/packages/contracts-bedrock/contracts/libraries/Types.sol#L33-L38
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